标签:think space integer 强连通分量 pst 连通 ted div printf
题目:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 38415 | Accepted: 15658 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Cow 3 is the only cow of high popularity.
思路:
代码:
#include <iostream> #include <vector> using namespace std; const int size = 1e4 + 1; vector<int> graph[size]; vector<int> reverse[size]; int order[size];//栈 int pos = 0;//用于order[]的索引 bool marked[size]; bool marked2[size]; int ans = 0;//连通分支数 int DAG[size];//分离强连通分量 int out[size];//DAG的出度,一共只有强连通分支数那么多个点 void init(int N)//初始化 { pos = ans = 0; for(int i = 1; i <= N; i++) { marked[i] = false; marked2[i] = false; graph[i].clear(); reverse[i].clear(); DAG[i] = 0; out[i] = 0; } } void dfsReverseOrder(int x) { marked[x] = true; for(int i = 0; i < reverse[x].size(); i++) { if(!marked[reverse[x][i]]) dfsReverseOrder(reverse[x][i]); } order[pos++] = x; } void dfs(int x) { DAG[x] = ans; marked2[x] = true; for(int i = 0; i < graph[x].size(); i++) { if(!marked2[graph[x][i]]) { dfs(graph[x][i]); } else if(DAG[graph[x][i]] != DAG[x])//和计算出度有关 out[ans] = 1; } } void Kosaraju(int N) { for(int i = 1; i <= N; i++) { if(!marked[i]) dfsReverseOrder(i); } pos--; for(; pos >= 0;pos--) { if(!marked2[order[pos]]) { dfs(order[pos]); ans++; } } } int main() { int N, M; int a, b; while(cin >> N >> M) { init(N); //输入 for(int i = 0; i < M; i++) { cin >> a >> b; graph[a].push_back(b); reverse[b].push_back(a); } Kosaraju(N); int count = 0; int flag; for(int i = 0; i < ans; i++)//找出度为0的强连通分支的个数 { if(out[i] == 0) { count++; flag = i; } } int num = 0; if(count == 1)//若只有一个出度为0的强连通分支 { for(int i = 1; i <= N; i++)//计算该强连通分支内点的个数 { if(DAG[i] == flag) num++; } printf("%d\n", num); } else printf("%d\n", 0); } return 0; }
Popular Cows//强连通分支Kosaraju加缩点
标签:think space integer 强连通分量 pst 连通 ted div printf
原文地址:https://www.cnblogs.com/w-j-c/p/9218978.html