poj 2186 Popular Cows

poj 2186 Popular Cows
写了好长时间。。。。才过得。 太不容易了


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,  0 sizeof (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,  0 sizeof (judge));
 75          memset(degree,  0 sizeof (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  }



你可能感兴趣的:(poj 2186 Popular Cows)