poj2186Popular Cows【强连通】【debug两小时】

来源:互联网 发布:linux 系统日志 命令 编辑:程序博客网 时间:2024/04/19 17:57

这个题我调试两个小时,快调哭了都

写一下心得

 

大意:告诉你一群牛  有n头 (n<10^4)

然后告诉你m对羡慕关系  如  a牛羡慕b牛

并且羡慕可以传递  如a羡慕b  b羡慕c  则a羡慕c

现在问有多少只牛是被所有的牛羡慕的

 

分析:我的第一个思路是遍历每个牛 然后从每个牛建立反向边  然后dfs看能否扫到所有的牛  但是这样时间复杂度O(n*(n + e) )  承受不住

后来想到可以像flody传递闭包那样但是同样时间复杂度承受

后来想到这个可以强连通一下子

 

我们首先想这么一个问题
对于一个有向无环图  

满足一个牛被所有牛都羡慕的条件是  :  1  图连通  2  该牛的出度为零(因为他是被所有牛都羡慕的那只  然后如果他再羡慕其他的牛  就会形成环)

对于本题是有环的   用强连通  进行缩点  变成一个有向无环图  再根据那俩条件进行判定即可

 

但是写的时候  首先是我把图中有孤立点这种情况忽略了

然后就是  脑残的break之后……想起来就心痛啊

代码:

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 using namespace std;  5   6 const int maxn = 50005;  7   8 int n, m;  9 int tot, cnt; 10 struct Node { 11     int to, next; 12 }e[maxn]; 13 int head[maxn]; 14  15 void add(int u, int v) { 16     e[tot].to = v; 17     e[tot].next = head[u]; 18     head[u] = tot++; 19 } 20 int s[maxn]; 21 int ins[maxn]; 22 int sc; 23 int ans; 24 int num[maxn]; 25  26 int low[maxn], dfn[maxn]; 27  28 void init() { 29     tot = 1; 30     memset(head, 0, sizeof(head)); 31     memset(low, 0, sizeof(low)); 32     memset(dfn, 0, sizeof(dfn)); 33     memset(ins, 0, sizeof(ins)); 34     memset(num, 0, sizeof(num)); 35     cnt = 1; 36     sc = 0; 37     ans = 0; 38 } 39  40 void dfs(int u) { 41     s[sc++] = u; 42     ins[u] = 1; 43     for(int i = head[u]; i; i = e[i].next) { 44         int v = e[i].to; 45         if(!dfn[v]) { 46             dfn[v] = low[v] = cnt++; 47             dfs(v); 48             low[u] = min(low[u], low[v]); 49         } else if(ins[v] && !num[v]) { 50             low[u] = min(low[u], dfn[v]); 51         } 52     } 53     if(low[u] == dfn[u]) { 54         ans++; 55         int x; 56         do { 57             x = s[--sc]; 58             num[x] = ans; 59             ins[x] = 0; 60         } while(x != u); 61     } 62  63 } 64 int outed[maxn]; 65  66 int main() { 67     int u, v; 68     while(EOF != scanf("%d %d",&n, &m) ) { 69         init(); 70         for(int i = 1; i <= m; i++) { 71             scanf("%d %d",&u, &v); 72             add(u, v); 73         } 74         for(int i = 1; i <= n; i++) { 75             if(!dfn[i]) { 76                 dfn[i] = low[i] = cnt++; 77                 dfs(i); 78             } 79         } 80     //    for(int i = 1; i <= n; i++) { 81     //        printf("%d ", num[i]); 82     //    } puts(""); 83         int ans_num = -1; 84         memset(outed, 0, sizeof(outed)); 85         for(int i = 1; i <= n; i++) { 86 //            printf("i = %d\n", i); 87             if(num[i] == 0) { 88                 ans_num = 0; 89                 break; 90             } 91             for(int j = head[i]; j ; j = e[j].next) { 92                 int x = e[j].to; 93                 if(num[i] != num[x]) { 94                     outed[num[i]]++; 95                 } 96             } 97         } 98     //    for(int i = 1; i <= n; i++) { 99     //        printf("*%d ", outed[i]);100     //    } puts("");101     //    printf("ans = %d\n", ans);102         int flag = 0;103         if(ans_num != 0) {104             ans_num = 0;105             int ax = 0;106             for(int i = 1; i <= ans; i++) {107                 if(outed[i] == 0) {108                     flag++;109                     if(flag >= 2) {110                         ans_num = 0;111                         break;112                     }113                     ax = i;114                 }115             }116             if(flag < 2) {117                 for(int i = 1; i <= n; i++) {118                     if(num[i] == ax) {119                         ans_num++;120                     }121                 }122             }123         }124         printf("%d\n", ans_num);125     }126     return 0;127 }
View Code

 

0 0
原创粉丝点击