标签:cstring clu tran ota scan most air one int
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 35035 | Accepted: 14278 |
3 3 1 2 2 1 2 3
1
1 //2017-08-20 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <vector> 7 8 using namespace std; 9 10 const int N = 10010; 11 vector<int> G[N];//邻接表存图 12 vector<int> rG[N];//存反向图 13 vector<int> vs;//后序遍历顺序的顶点列表 14 bool vis[N]; 15 int cmp[N];//所属强连通分量的拓扑序 16 17 void add_edge(int u, int v){ 18 G[u].push_back(v); 19 rG[v].push_back(u); 20 } 21 22 //input: u 顶点 23 //output: vs 后序遍历顺序的顶点列表 24 void dfs(int u){ 25 vis[u] = true; 26 for(int i = 0; i < G[u].size(); i++){ 27 int v = G[u][i]; 28 if(!vis[v]) 29 dfs(v); 30 } 31 vs.push_back(u); 32 } 33 34 //input: u 顶点编号; k 拓扑序号 35 //output: cmp[] 强连通分量拓扑序 36 void rdfs(int u, int k){ 37 vis[u] = true; 38 cmp[u] = k; 39 for(int i = 0; i < rG[u].size(); i++){ 40 int v = rG[u][i]; 41 if(!vis[v]) 42 rdfs(v, k); 43 } 44 } 45 46 //Strongly Connected Component 强连通分量 47 //input: n 顶点个数 48 //output: k 强连通分量数; 49 int scc(int n){ 50 memset(vis, 0, sizeof(vis)); 51 vs.clear(); 52 for(int u = 0; u < n; u++) 53 if(!vis[u]) 54 dfs(u); 55 int k = 0; 56 memset(vis, 0, sizeof(vis)); 57 for(int i = vs.size()-1; i >= 0; i--) 58 if(!vis[vs[i]]) 59 rdfs(vs[i], k++); 60 return k; 61 } 62 63 void solve(int n){ 64 int k = scc(n); 65 int u = 0, ans = 0; 66 for(int v = 0; v < n; v++){ 67 if(cmp[v] == k-1){ 68 u = v; 69 ans++; 70 } 71 } 72 memset(vis, 0, sizeof(vis)); 73 rdfs(u, 0); 74 for(int i = 0; i < n; i++){ 75 if(!vis[i]){ 76 ans = 0; 77 break; 78 } 79 } 80 printf("%d\n", ans); 81 } 82 83 int main() 84 { 85 int n, m; 86 while(scanf("%d%d", &n, &m)!=EOF){ 87 int u, v; 88 for(int i = 0; i < n; i++){ 89 G[i].clear(); 90 rG[i].clear(); 91 } 92 while(m--){ 93 scanf("%d%d", &u, &v); 94 u--; v--; 95 add_edge(u, v); 96 } 97 solve(n); 98 } 99 100 return 0; 101 }
标签:cstring clu tran ota scan most air one int
原文地址:http://www.cnblogs.com/Penn000/p/7399829.html