首页 > 代码库 > 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(割点)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。