hdu 4587 TWO NODES 暴力枚举+tarjan
生活随笔
收集整理的這篇文章主要介紹了
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; }?
轉載于:https://www.cnblogs.com/dishu/p/4529673.html
總結
以上是生活随笔為你收集整理的hdu 4587 TWO NODES 暴力枚举+tarjan的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php伪静态
- 下一篇: PHP常用功能块_错误和异常处理 — p