hdu 4587 TWO NODES 暴力枚举+tarjan
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587
题意是拿掉两个点
求最多可以把整个图分成几个联通块
注意到有一个模板是可以通过找割点来快速求出
“删一个点最多可以把整个图分成几个联通块”
所以这个时候要观察到点数只有5000
要大胆暴力枚举另一个点
即
先枚举一个点,然后另一个点套用tarjan模板
即可求出答案
#include <cstring> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <cstdio> #include <stack> #include <vector> #include <queue> #include <map> #include <set> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> P; const int maxn = 5010; const int maxm = 10010; struct Edge { int to, next; bool cut; }edge[maxm]; int head[maxn], tot; int Low[maxn], DFN[maxn], Stack[maxn]; int Index, top; bool Instack[maxn]; bool cut[maxn]; int add_block[maxn]; int bridge; bool flag[maxn]; void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; edge[tot].cut = false; head[u] = tot++; } void Tarjan(int u, int pre) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; int son = 0; for(int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(v == pre || flag[v] == true) continue; if(!DFN[v]) { son++; Tarjan(v, u); if(Low[u] > Low[v]) Low[u] = Low[v]; if(Low[v] > DFN[u]) { bridge++; edge[i].cut = true; edge[i^1].cut = true; } if(u != pre && Low[v] >= DFN[u]) { cut[u] = true; add_block[u]++; } } else if(Low[u] > DFN[v]) Low[u] = DFN[v]; } if(u == pre & son > 1) cut[u] = true; if(u == pre) add_block[u] = son - 1; Instack[u] = false; top--; } void solve(int N) { int ans = 0; for(int k = 1; k <= N; k++) { flag[k] = true; memset(DFN, 0, sizeof(DFN)); memset(Instack, 0, sizeof(Instack)); memset(add_block, 0, sizeof(add_block)); memset(cut, false, sizeof(cut)); for(int i = 0; i < tot; i++) edge[i].cut = false; Index = top = 0; int cnt = 0; for(int i = 1; i <= N; i++) { if(flag[i]) continue; if(!DFN[i]) { Tarjan(i, i); cnt++; } } int anss = 0; for(int i = 1; i <= N; i++) if(flag[i] == false) anss = max(anss, cnt + add_block[i]); // if(N-1 == cnt) // ans--; ans = max(ans, anss); flag[k] = false; } printf("%d\n", ans); } void init() { tot = 0; memset(head, -1, sizeof(head)); } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int n, m; while(scanf("%d%d", &n, &m) == 2) { init(); for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); u++; v++; addedge(u, v); addedge(v, u); } solve(n); } return 0; }