poj2112 Electricity(割点应用)

来源:互联网 发布:提高淘宝店铺关注率 编辑:程序博客网 时间:2024/06/05 05:59

给定一张无向图,求删除某个点后图形成的连通快数目,求最大。
邻接表会TLE。。。

统计每个割点所连接的双连通数目,和全部有多少个连通快。

const int maxn = 10010;// vector<vector<int> > G;int head[maxn], pnt[maxn<<2], nxt[maxn<<2], ecnt;int dfn[maxn], low[maxn], depth;int belong[maxn], block;int in[maxn];int cnt[maxn];int n, m;int ans;void dfs(int u,int root) {    dfn[u] = low[u] = ++depth;    in[u] = 1;    // st.push(u);    int child = 0;    // int Size = G[u].size();    for (int i = head[u];~i;i = nxt[i]) {        int v = pnt[i];        if (dfn[v] == -1) {            child++;            dfs(v, root);            low[u] = min(low[u], low[v]);            if (low[v] >= dfn[u] && u != root) cnt[u]++;        }else if (in[v])low[u] = min(low[u], dfn[v]);    }    if (u == root && child >= 2) cnt[u] = child - 1;    ans = max(ans, cnt[u]);}void addedge(int u,int v) {    pnt[ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt++;}int main(int argc, const char * argv[]){        // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    // clock_t _ = clock();    while(scanf("%d%d", &n, &m) != EOF) {        if (n == 0 && m == 0) break;        // G.clear();G.resize(n + 2);        memset(head, -1,sizeof head), ecnt = 0;        int u, v;        for (int i = 0;i < m;++i) {            scanf("%d%d", &u, &v);            // G[u].push_back(v);            // G[v].push_back(u);            addedge(u, v);addedge(v, u);        }        if (m == 0) {printf("%d\n", n - 1);continue;}        memset(dfn, -1,sizeof dfn), depth = block = 0;        memset(cnt, 0, sizeof cnt);        ans = 0;        for (int i = 0;i < n;++i)            if (dfn[i] == -1) dfs(i, i), block++;        // int ans = 0;        // for (int i = 0;i < n;++i)        //     ans = max(ans, block + cnt[i]);        // cout << ans << endl;        printf("%d\n", ans + block);    }    // printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC);    return 0;}
0 0
原创粉丝点击