题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4587
题意:
删除两个点,使连通块的数目最大化
题解:
枚举删除第一个点,然后对删除了第一个点的图跑割点更新答案。
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> using namespace std; const int maxn = 5555; vector<int> G[maxn]; int n,m; int pre[maxn], low[maxn], iscut[maxn], dfs_clock; int dfs(int u, int fa,int tag) { int lowu = pre[u] = ++dfs_clock; int child = 0; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == tag||v==fa) continue; if (!pre[v]) { child++; int lowv = dfs(v, u, tag); lowu = min(lowu, lowv); if (lowv >= pre[u]) { iscut[u]++; } } else if (pre[v] < pre[u] && v != fa) { lowu = min(lowu, pre[v]); } } if (fa < 0 && child == 1) iscut[u]--; else if (fa < 0) iscut[u]--; low[u] = lowu; return lowu; } void init() { for (int i = 0; i < n; i++) G[i].clear(); } int main() { while (scanf("%d%d", &n, &m) == 2 && n) { init(); for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } int ans = -1; for (int i = 0; i < n; i++) { memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); dfs_clock = 0; int cnt = 0; for (int j = 0; j<n; j++) { if (j == i) continue; if (!pre[j]) { cnt++; dfs(j, -1, i); } } for (int j = 0; j < n; j++) { if (j == i) continue; ans = max(ans, iscut[j] + cnt); } } printf("%d ", ans); } return 0; }