强联通 poj 2762

t个样例    (注意清零)

n个点m条边 有向;

任意2点是否能从a->b或者b->a;

Yes  No

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 #include<queue>
  5 #include<math.h>
  6 #include<stack>
  7 
  8 using namespace std;
  9 
 10 #define MAXN  20000
 11 #define MAXN1 10000
 12 int cnt,k,num;
 13 struct edg
 14 {
 15     int next,to,fr;
 16 
 17 }x[MAXN+10];
 18 int head[MAXN1],dfn[MAXN1],low[MAXN1],f[MAXN1];
 19 bool vis[MAXN1];
 20 int in[MAXN1];
 21 
 22 void add(int u,int v)
 23 {
 24     x[cnt].fr=u;
 25     x[cnt].next=head[u];
 26     x[cnt].to=v;
 27     head[u]=cnt++;
 28 }
 29 stack<int>s;
 30 
 31 void dfs(int u)
 32 {
 33     low[u]=dfn[u]=k++;
 34     s.push(u);
 35     vis[u]=1;
 36     int i;
 37     for(i=head[u];i!=-1;i=x[i].next)
 38     {
 39         if(!dfn[x[i].to])
 40         {
 41             dfs(x[i].to);
 42             low[u]=min(low[u],low[x[i].to]);
 43         }
 44         else if(vis[x[i].to])
 45             low[u]=min(low[u],dfn[x[i].to]);
 46     }
 47     if(low[u]==dfn[u]) //强联通分量
 48     {
 49         num++;
 50         while(!s.empty())
 51         {
 52             int now=s.top();
 53             s.pop();
 54             f[now]=num;  //新的点
 55             vis[now]=0;
 56             if(u==now)break;
 57         }
 58     }
 59 }
 60 queue<int>q1;
 61 
 62 int judge()
 63 {
 64     int i;
 65     while(!q1.empty())q1.pop();   //很重要
 66     for(i=1;i<=num;i++)
 67     {
 68         if(!in[i])
 69             q1.push(i);
 70     }
 71     if(q1.size()>1)return 0;   //入度为0的点1个
 72 
 73     while(!q1.empty())
 74     {
 75         int now=q1.front();
 76         q1.pop();
 77         for(i=head[now];i!=-1;i=x[i].next)
 78         {
 79             in[x[i].to]--;
 80             if(!in[x[i].to])
 81                 q1.push(x[i].to);
 82         }
 83         if(q1.size()>1)return 0;
 84     }
 85     return 1;
 86 }
 87 
 88 int main()
 89 {
 90     int t;
 91     scanf("%d",&t);
 92 
 93     while(t--)
 94     {
 95         int n,m;
 96         scanf("%d%d",&n,&m);
 97         int i;
 98         memset(head,-1,sizeof(head));
 99         cnt=0;
100         for(i=1;i<=m;i++)
101         {
102             int a,b;
103             scanf("%d%d",&a,&b);
104             add(a,b);
105         }
106         k=1;
107         num=0;
108         while(!s.empty())s.pop();
109         memset(dfn,0,sizeof(dfn));
110         memset(low,0,sizeof(low));
111         memset(vis,0,sizeof(vis));
112         memset(f,0,sizeof(f));
113         for(i=1;i<=n;i++)
114         {
115             if(!dfn[i])
116                 dfs(i);
117         }
118         int en=cnt;
119         memset(head,-1,sizeof(head));
120         memset(in,0,sizeof(in));
121         cnt=0;
122         for(i=0;i<en;i++)  //重新建图
123         {
124             int a,b;
125             a=f[x[i].fr];
126             b=f[x[i].to];
127             if(a!=b)
128             {
129                 add(a,b);
130                 in[b]++;
131             }
132         }
133         if(judge())
134             printf("Yes
");
135         else
136             printf("No
");
137     }
138 
139     return 0;
140 }
原文地址:https://www.cnblogs.com/cherryMJY/p/6057440.html