ZOJ 3630 —— Information

来源:互联网 发布:shadowsock linux 编辑:程序博客网 时间:2024/06/07 06:20

原题:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3630


题意:有n个点,m条边,删除一个点后,得到强连通分量点数的最大值,求最大点数的最小值;

注意:点数 = 1 时为 0 ;

思路:枚举每个点为删除点,求出每次强连通分量的最大值,然后取最小的;


#include<cstdio>#include<string>#include<cstring>#include<vector>#include<algorithm>#define inf 0x3f3f3f3fusing namespace std;const int maxn = 110;const int maxm = 10000;int n, m;int DFN[maxn], Low[maxn], Stack[maxn];bool Instack[maxn];int Time, taj, top;int head[maxn], edgenum;struct Edge{int from, to, next;}edge[maxm];int cnt;vector<int>bcc[maxn];int Tarjan(int u, int k){DFN[u] = Low[u] = ++Time;Stack[top++] = u;Instack[u] = true;for(int i = head[u];i != -1;i = edge[i].next){int v = edge[i].to;if(v == k)continue;if(DFN[v] == -1){Tarjan(v, k);Low[u] = min(Low[u], Low[v]);}else if(Instack[v] && Low[u] > DFN[v])Low[u] = DFN[v];}if(Low[u] == DFN[u]){cnt = 0;taj++;bcc[taj].clear();while(1){int now = Stack[--top];cnt++;Instack[now] = false;bcc[taj].push_back(now);if(now == u)break;}}return cnt;}void add(int u, int v){edge[edgenum].from = u;edge[edgenum].to = v;edge[edgenum].next = head[u];head[u] = edgenum++;}void init(){memset(head, -1, sizeof head);edgenum = 0;}void init_taj(){memset(DFN, -1, sizeof DFN);memset(Instack, false, sizeof Instack);Time = taj = top = 0;}int Find_max(){int maxx = -1;for(int i = 1;i<=taj;i++)maxx = max(maxx, (int)bcc[i].size());return maxx;}int main(){while(~scanf("%d%d", &n, &m)){init();while(m--){int u, v;scanf("%d%d", &u, &v);add(u, v);}int ans = inf;for(int t = 0;t<n;t++){init_taj();for(int i = 0;i<n;i++){if(i == t)continue;if(DFN[i] == -1)Tarjan(i, t);}int tmp = Find_max();ans = min(ans, tmp);}if(ans == 1)ans = 0;printf("%d\n", ans);}return 0;}


0 0
原创粉丝点击