首页 > 代码库 > hdu4587-TWO NODES(割点)

hdu4587-TWO NODES(割点)

#include <bits/stdc++.h>using namespace std;const int N = 5005;const int M = 100010;struct Edge {    int to, next;} edge[M];int head[N];int cntE;void addedge(int u, int v) {    edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;    edge[cntE].to = u; edge[cntE].next = head[v]; head[v] = cntE++;}int dfn[N], low[N], idx;int stk[N], top;bool cut[N];int block[N];// 一个割点可能在很多个连通分量// 如果一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈//  那么这个双连通分量的其他顶点也在某个奇圈中// 如果一个双连通分量含有奇圈,则他必定不是一个二分图。反过来也成立,这是一个充要条件。int no;// block[i] 是去掉i这个节点能够多几个联通块void tarjan(int u, int fa) {    dfn[u] = low[u] = ++idx;    stk[top++] = u;    block[u] = 0;    int son = 0;    for (int i = head[u]; ~i; i = edge[i].next) {        int v = edge[i].to;        if (v == fa || v == no) continue;        if (!dfn[v]) {            son++;            tarjan(v, u);            low[u] = min(low[u], low[v]);            if (u != fa && low[v] >= dfn[u]) {                cut[u] = true;                block[u]++;            }            /* 求每一个连通分量            if (low[v] >= dfn[u]) {                int x;                do {                    x = stk[--top];                    push(x);                } while (x != v);                push(u);            }            */        } else {            low[u] = min(low[u], dfn[v]);        }    }    if (u == fa) {        if (son > 1) cut[u] = 1;        block[u] = son-1;    }}void init() {    memset(dfn, 0, sizeof dfn);    top = idx = cntE = 0;}int main(){    int n, m;    while (~scanf("%d%d", &n, &m)) {        int u, v;        memset(head, -1, sizeof head);        for (int i = 0; i < m; ++i) {            scanf("%d%d", &u, &v);            addedge(u, v);        }        int ans = 0;        for (u = 0; u < n; ++u) {            init(); int cnt = 0; no = u;            for (v = 0; v < n; ++v) {                if (v != u && !dfn[v]) {                    tarjan(v, v);                    cnt++;                }            }            for (v = 0; v < n; ++v) {                if (v != u) ans = max(ans, cnt + block[v]);            }        }        printf("%d\n", ans);    }    return 0;}

 

hdu4587-TWO NODES(割点)