poj 2762 Going from u to v or from v to u?(强连通、缩点、拓扑)

题意:(理解错了)在一个洞穴中有多个room,要求任意选两个room:u、v,都能保证u、v之间有通路,注意洞穴中的路是有向边。、

分析:强连通子图中的点必然两两之间可以互通,两个强连通子图之间有通路,必须在树上构成父子关系(不一定相邻),又两两之间有通路,即任意两个点u、v都存在父子关系——所有强连通子图构成一条链。

错误:tarjin初始化忘记更新scc_cnt=dfs_clock=0;

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<stack>
  5 #include<vector>
  6 #include<algorithm>
  7 using namespace std;
  8 
  9 const int MAXN=1111;
 10 
 11 struct Edge{
 12     int v,next;
 13     Edge(){}
 14     Edge(int _v,int _next):v(_v),next(_next){}
 15 }edge[MAXN*10];
 16 
 17 struct Tp{
 18     int u,c;
 19     Tp(){}
 20     Tp(int _u,int _c):u(_u),c(_c){}
 21 };
 22 
 23 int pre[MAXN],low[MAXN],sccno[MAXN],scc_cnt,dfs_clock;
 24 int head[MAXN],tol;
 25 stack<int>stk;
 26 
 27 //int mp[MAXN][MAXN];//去重边反而跑的时间更长
 28 vector<int>G[MAXN];
 29 
 30 int in[MAXN],color[MAXN];
 31 queue<Tp>q;
 32 
 33 void init()
 34 {
 35     tol=0;
 36     memset(head,-1,sizeof(head));
 37 }
 38 
 39 void add(int u,int v)
 40 {
 41     edge[tol]=Edge(v,head[u]);
 42     head[u]=tol++;
 43 }
 44 
 45 void dfs(int u)
 46 {
 47     int v;
 48     pre[u]=low[u]=++dfs_clock;
 49     stk.push(u);
 50     for(int i=head[u];i!=-1;i=edge[i].next)
 51     {
 52         v=edge[i].v;
 53         if(!pre[v]){
 54             dfs(v);
 55             low[u]=min(low[u],low[v]);
 56         }else if(!sccno[v])
 57             low[u]=min(low[u],pre[v]);
 58     }
 59     if(pre[u]==low[u]){
 60         scc_cnt++;
 61         do{
 62             v=stk.top();
 63             stk.pop();
 64             sccno[v]=scc_cnt;
 65         }while(u!=v);
 66     }
 67 }
 68 
 69 void find_scc(int n)
 70 {
 71     dfs_clock=scc_cnt=0;
 72     memset(pre,0,sizeof(pre));
 73     memset(low,0,sizeof(low));
 74     memset(sccno,0,sizeof(sccno));
 75 
 76     for(int i=1;i<=n;i++)
 77         if(!pre[i])
 78             dfs(i);
 79 }
 80 
 81 int main()
 82 {
 83     int T;
 84     int n,m;
 85     scanf("%d",&T);
 86     while(T--)
 87     {
 88         scanf("%d%d",&n,&m);
 89 
 90         init();
 91         for(int i=0;i<m;i++)
 92         {
 93             int u,v;
 94             scanf("%d%d",&u,&v);
 95             add(u,v);
 96         }
 97 
 98         find_scc(n);
 99 
100         memset(in,0,sizeof(in));
101         for(int i=1;i<=scc_cnt;i++)
102             G[i].clear();
103         //memset(mp,0,sizeof(mp));
104         for(int i=1;i<=n;i++)
105             for(int j=head[i];j!=-1;j=edge[j].next)
106                 if(sccno[i]!=sccno[edge[j].v]){
107                     //if(mp[sccno[i]][sccno[edge[j].v]]==0){
108                         G[sccno[i]].push_back(sccno[edge[j].v]);
109                         //mp[sccno[i]][sccno[edge[j].v]]=1;
110                         in[sccno[edge[j].v]]++;
111                     //}
112                 }
113         for(int i=1;i<=scc_cnt;i++)
114             if(!in[i])
115                 q.push(Tp(i,1));
116 
117         memset(color,0,sizeof(color));
118         Tp e;
119         while(!q.empty())
120         {
121             e=q.front();q.pop();
122             color[e.c]++;
123             int sz=G[e.u].size();
124             for(int i=0;i<sz;i++)
125             {
126                 in[G[e.u][i]]--;
127                 if(in[G[e.u][i]]==0){
128                     q.push(Tp(G[e.u][i],e.c+1));
129                 }
130             }
131         }
132 
133         int flog=1;
134         for(int i=1;i<=e.c;i++)
135             if(color[i]>1){
136                 flog=0;
137                 break;
138             }
139 
140         if(!flog)
141             printf("No\n");
142         else
143             printf("Yes\n");
144     }
145     return 0;
146 }
View Code

 

posted @ 2013-10-05 13:11  Thousand Sunny  阅读(480)  评论(0编辑  收藏  举报