pku 2762 Going from u to v or from v to u? 强联通分支缩点+找最长链

pku 2762 Going from u to v or from v to u? 强联通分支缩点+找最长链

题意是这样:一个有向图,问能否取任意两个不同的节点u,v,u->v或者v->u存在路径。
首先还是缩点,因为强联通分量里肯定任意两点可达的。缩点后,图变成DAG
下面就到了关键的部分了,什么情况下u、v互相不可达呢?显然,u,v在两条不同的链上。
然后就很简单了,找最长链也可意,拓扑排序判断序列唯一性也可以。我是按后者做的。
  1  import  java.io. * ;
  2  import  java.util.Arrays;
  3  import  java.util.LinkedList;
  4  public   class  Main {
  5 
  6       /**
  7       *  @param  args
  8        */
  9 
 10       static   int  g[] = new   int [ 1001 ],ng[] = new   int  [ 1001 ],bid[] = new   int [ 1001 ],stack[] = new   int [ 1001 ],top;
 11       static   int  v[] = new   int [ 12005 ],nxt[] = new   int [ 12005 ],c,n,m;
 12       static   int  low[] = new   int [ 1001 ],cnt,bc;
 13       static   int  degree[] = new   int [ 1001 ];
 14       static  LinkedList < Integer >  q = new  LinkedList < Integer > ();
 15       static   void  tarjan( int  pos)
 16      {
 17           int  nowid = cnt ++ ;
 18          low[pos] = nowid;
 19          stack[ ++ top] = pos;
 20           for ( int  p = g[pos];p !=- 1 ;p = nxt[p])
 21          {
 22               if (low[v[p]] ==- 1 )
 23                  tarjan(v[p]);
 24              low[pos] = Math.min(low[pos],low[v[p]]);
 25          }
 26           if (low[pos] >= nowid)
 27          {
 28               do
 29              {
 30                  bid[stack[top]] = bc;
 31                  low[stack[top]] = Integer.MAX_VALUE;
 32              } while (stack[top -- ] != pos);
 33              bc ++ ;
 34          }
 35      }
 36       static   void  dfs( int  pos)
 37      {
 38          low[pos] = 1 ;
 39          stack[bid[pos]] = 1 ;
 40           for ( int  p = g[pos];p !=- 1 ;p = nxt[p])
 41               if (low[v[p]] ==- 1 )
 42                  dfs(v[p]);
 43      }
 44       public   static   void  main(String[] args)  throws  IOException{
 45          StreamTokenizer in = new  StreamTokenizer( new  BufferedReader( new  InputStreamReader(System.in)));
 46           int  testcase;
 47          in.nextToken();
 48          testcase = ( int )in.nval;
 49           while ((testcase -- ) != 0 )
 50          {
 51               int  a,b;
 52              in.nextToken();
 53              n = ( int )in.nval;
 54              in.nextToken();
 55              m = ( int )in.nval;
 56              Arrays.fill(g,  - 1 );
 57              c = 0 ;
 58               while ((m -- ) != 0 )
 59              {
 60                  in.nextToken();
 61                  a = ( int )in.nval;
 62                  in.nextToken();
 63                  b = ( int )in.nval;
 64                  v[c] = b;
 65                  nxt[c] = g[a];
 66                  g[a] = c ++ ;
 67              }
 68              Arrays.fill(low, - 1 );
 69              Arrays.fill(bid, - 1 );
 70              cnt = bc = 0 ;
 71              top =- 1 ;
 72               for ( int  i = 1 ;i <= n;i ++ )
 73                  if (low[i] ==- 1 )
 74                      tarjan(i);
 75              Arrays.fill(ng, - 1 );
 76               for ( int  i = 1 ;i <= n;i ++ )
 77                   for ( int  p = g[i];p !=- 1 ;p = nxt[p])
 78                       if (bid[v[p]] != bid[i])
 79                      {
 80                          v[c] = bid[v[p]];
 81                          nxt[c] = ng[bid[i]];
 82                          ng[bid[i]] = c ++ ;
 83                      }
 84              q.clear();
 85              Arrays.fill(degree, 0 );
 86               for ( int  i = 0 ;i < bc;i ++ )
 87                   for ( int  p = ng[i];p !=- 1 ;p = nxt[p])
 88                      degree[v[p]] ++ ;
 89               for ( int  i = 0 ;i < bc;i ++ )
 90                   if (degree[i] == 0 )
 91                      q.add(i);
 92               int  count = 0 ;
 93               while ( ! q.isEmpty() && q.size() <= 1 )
 94              {
 95                   int  top = q.poll();
 96                  count ++ ;
 97                   for ( int  p = ng[top];p !=- 1 ;p = nxt[p])
 98                       if ( true )
 99                      {
100                          degree[v[p]] -- ;
101                           if (degree[v[p]] == 0 )
102                              q.add(v[p]);
103                      }
104              }
105               if (q.isEmpty() && count == bc)
106                 System.out.println( " Yes " );
107               else
108                  System.out.println( " No " );
109              
110          }
111                      
112      }
113 
114  }
115 


你可能感兴趣的:(pku 2762 Going from u to v or from v to u? 强联通分支缩点+找最长链)