MemoryGarden's Blog

努力 -----------大能猫

C++博客 首页 新随笔 联系 聚合 管理
  118 Posts :: 11 Stories :: 20 Comments :: 0 Trackbacks
写了好长时间。。。。才过得。太不容易了


http://acm.pku.edu.cn/JudgeOnline/problem?id=2186

题目大意 : 有一些牛,然后他们互相仰慕,为有向图,仰慕可传递, a仰慕b, b仰慕c,a就仰慕c,让你求

解被所有牛仰慕的牛的个数。(貌似要找大牛呢。。。。汗)


思路: 好多大牛在disduss 里面也说了,就是有向图的强连通分量,然后讲这个强连通分两压缩成一个点,这样,再重新构图,在新构的图中,找到出度为0的点,代表这个连同分量里面的点 不指向别的连同分量的点,也就是说,这些牛不仰慕别的牛。当然,如果这样的,出度为0的连同分两的点大于1,也就是重新生成的图不是连同的话,那么就代表 肯定不存在被所有牛都仰慕的牛了。

ps : 上来搞了一把矩阵。。。然后wa。。。然后找报告。。。然后找到代码。。。然后rand数据。。。然后比较。。。最后竟然发现报告的程序有bug。。。。 瀑布汗。。。。。最后感觉改的没问题了。。。交。。。。mle。。。。瞬间崩塌。。。。早晨起来接着搞。。。。最后链存过的。。。。。



方法 : 求解连同分量正dfs,求解后续遍历序号,按序号从大到小dfs原图的逆图。这样,能求找到每个点属于哪个连同分量。 然后就一顿乱gao。。。时间复杂度巨高。。。。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #define max 10001
  4 using namespace std;
  5 int m, n, judge[max], back[max], backnum, tback[max], degree[max], belon[max];
  6 struct P{
  7     int v;
  8     P* next;
  9 };
 10 void zdfs(int u, P** map){
 11     int i;
 12     judge[u] = 1;
 13     P* p = map[u];
 14     while(p){
 15         if(!judge[p->v])
 16             zdfs(p->v, map);
 17         p = p->next;
 18     }
 19     back[u] = ++backnum;
 20 }
 21 void fdfs(int u, P** tmap, int d){
 22     int i;
 23     P* p = tmap[u];
 24     belon[u] = d;
 25     judge[u] = 1;
 26     while(p){
 27         if(!judge[p->v])
 28             fdfs(p->v, tmap, d);
 29         p = p->next;
 30     }
 31 }
 32 void fengle(P** map, P** tmap){
 33     int i, j, kn = 0, u, v, wrong = 0, ele = 0, res = 0;P* p;
 34     for(i = 1; i <= m; i++){
 35         if(!judge[i])
 36             zdfs(i, map);
 37     }
 38     for(i = 1; i <= m; i++)
 39         tback[back[i]] = i;
 40     memset(judge, 0sizeof(judge));
 41     for(i = m, j = 1; i >= 1; i--){
 42         if(!judge[tback[i]]){
 43             fdfs(tback[i], tmap, j++);
 44             kn++;
 45         }
 46     }
 47     for(u = 1; u <= m; u++){
 48         p = map[u];
 49         while(p){
 50             v = p -> v;
 51             if(belon[u] != belon[v])
 52                 degree[belon[u]]++;
 53             p = p->next;
 54         }
 55     }
 56     for(i = 1; i <= kn; i++){
 57         if(!degree[i]){
 58             wrong++;
 59             ele = i;
 60         }
 61     }
 62     if(wrong > 1){
 63         printf("0\n");return;
 64     }
 65     for(i = 1; i <= m; i++)
 66         if(belon[i] == ele)
 67             res++;
 68     printf("%d\n", res);
 69 }
 70 int main(){
 71     int i, j, u, v;
 72     while(scanf("%d%d"&m, &n) != -1){
 73         P* map[max];P* tmap[max];P* l;P* t;
 74         memset(judge, 0sizeof(judge));
 75         memset(degree, 0sizeof(degree));
 76         backnum = 0;
 77         for(i = 1; i < max; i++)
 78             map[i] = tmap[i] = NULL;
 79         for(i = 0; i < n; i++){
 80             scanf("%d%d"&u, &v);
 81             l = new P;    //正图
 82             l->= v;
 83             l->next = map[u];
 84             map[u] = l;
 85             l = new P;  //反图
 86             l->= u;
 87             l->next = tmap[v];
 88             tmap[v] = l;
 89         }
 90         fengle(map, tmap);
 91         for(i = 1; i <= m; i++){ //释放
 92             l = map[i];
 93             while(map[i]){
 94                 l = map[i];
 95                 map[i] = map[i]->next;
 96                 delete l;
 97             }
 98         }
 99         for(i = 1; i <= m; i++){ //释放
100             l = tmap[i];
101             while(tmap[i]){
102                 l = map[i];
103                 tmap[i] = tmap[i]->next;
104                 delete l;
105             }
106         }
107     }
108     return 0;
109 }



posted on 2008-09-04 00:29 memorygarden 阅读(736) 评论(0)  编辑 收藏 引用 所属分类: 报告

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理