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

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

写一下心得

大意:告诉你一群牛  有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 }

时间: 2024-12-11 12:07:02

poj2186Popular Cows【强连通】【debug两小时】的相关文章

poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)

1 /* 2 题目大意:有N个cows, M个关系 3 a->b 表示 a认为b popular:如果还有b->c, 那么就会有a->c 4 问最终有多少个cows被其他所有cows认为是popular! 5 6 思路:强连通分量中每两个节点都是可达的! 通过分解得到最后一个连通分量A, 7 如果将所有的强连通分量看成一个大的节点,那么A一定是孩子节点(因为我们先 8 完成的是父亲节点的强连通分量)! 最后如果其他的强连通分量都可以指向A,那么 9 A中的每一个cow都会被其他cows所

poj2186 Popular Cows --- 强连通

给一个有向图,问有多少结点是其他所有结点都可以到达的. 等价于,在一个有向无环图上,找出度为0 的结点,如果出度为0的结点只有一个,那么这个就是答案,如果大于1个,则答案是0. 这题有环,所以先缩点.求唯一出度为0的强连通分量. #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<iostream> #define inf 0x3f3f3f3f

POJ 2186 Popular Cows --强连通分量

题意:给定一个有向图,问有多少个点由任意顶点出发都能达到. 分析:首先,在一个有向无环图中,能被所有点达到点,出度一定是0. 先求出所有的强连通分支,然后把每个强连通分支收缩成一个点,重新建图,这样,这个有向图就变成了一个有向无环图. 在这个新的图中,只需知道出度为0的点有几个即可. 如果出度为0的点超过1个,则输出0:否则输出出度为0的点所代表的那个强连通分支的分量数即可. 用Tarjan求强连通分量 代码: #include <iostream> #include <cstdio&g

西班牙充气教堂助你闪婚 两小时“搞定”婚礼(图)

充气教堂. 对国外的闪婚族而言,结婚时订不到教堂是个难题.侨居西班牙的英国商人迈克尔·吉尔发明可供出租的充气教堂,两小时"搞定"婚礼. 充气教堂充满气后高3.66米.内部长3.66米,最多可容纳60名来宾.别看是个充气教堂,它可谓"五脏俱全",有一般教堂象征的钟楼尖顶.花玻璃窗以及管风琴.长木凳.圣坛等. 教堂充气需要两小时,但30分钟就能把空气完全放掉,每次租借费用为2.5万英镑(约合4.2万美元). 吉尔现年45岁,在西班牙经营"极限充气"公

8月前端挑战-----如何做到这个月内每天下班学习两小时

你是否眼红别人风轻云淡,将优秀当成一种习惯?你不止一次的想要努力一把,奈何总是三天打鱼,然后无限循环? 你是否受够了这种得过且过,碌碌无为的日子?如果是这样的话,那就接受这个小挑战吧! 初衷: 前端发展日新月异,必须要经常学习,充电才能保证自己的竞争力.基于此,我想要发起一个督促自己每天下班坚持学习的活动,让有类似想要坚持学习而往往坚持不下去的同学参与进来,相互监督,最终提升自己,升职加薪! 愿景: 给自己一个坚持的理由,培养自己持之以恒的精神,和学习的习惯. 规则: 2017/8/3 至 20

poj2186--Popular Cows(强连通+缩点)

poj2186:题目链接 题目大意:有n头奶牛,m个关系,A B表示A奶牛认为B是备受关注的,这个关系具有继承性,比如:A B 和 B C那么A奶牛也会认为C是备受关注的,问有多少头奶牛是受到除自己以外所以人关注的 首先进行强连通,那么每个连通块中的点都是受到该连通块中其它点的关注的,进行缩点,原图变成一颗树,如果有且只有一个缩点以后的点的出度为0,那么这个点就是受到所有人关注的.记录下该点代表原图中的几个点,输出 不用考虑是否所有点在一个图中,因为如果不在一个图中,不会满足"有且只有一个缩点以

Poj2186Popular Cows

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31533   Accepted: 12817 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M &

下班后两小时,决定你将会成为怎样的人?

下班就累瘫倒了怎么办:用健身战胜累 上班通勤已经很累了,回家只想倒头就睡,根本没有力气再做业余活动,更无法动手动脑把业余活动做出什么成就来,这简直就是一个无法破的死循环,该怎么办!以实际经验告诉你,早晨去健身,去健身,去健身.那会不会让身体更累呢?你去试试看,真的去试试看.我从早晨健身后,整个一天都精神振奋的想大跳,观察我身边的健身妹子们,以前一个个都是加班狗,上班一年就一个个暮气沉沉,健身后一个个感觉都朝着网红路上走了.人的精神和外貌都改变成这样了,随时随地精神百倍!这些人现在干点啥都发朋友圈

90后大学生自创品牌口袋蜜如何在短短两小时众筹

“如果你真的想做一件事,全世界都会帮助你”,时下正风靡的“众筹”让这句话有了更直接的方式照进现实.从一个创业想法到寻找合作伙伴,到众筹10万元资金,51个众筹股东,“口袋蜜”用了2个小时的时间.时髦的“众筹”,让这个90后大学生的“白日梦”变成了现实. 创业故事 90后大学生众筹卖蜂蜜 秋意渐浓的武汉,“口袋蜜”的联合创始人彭梓俊和本报记者聊起了关于口袋蜜的创业故事. “90后都追求自由和个性,对于千篇一律的工作充满了槽点,对毫无个性的上班生活地点也早已厌倦”,正是基于这样的想法,今年7月,在毕