hdu1269强连通分量入门题

https://vjudge.net/contest/156688#problem

为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。
Input输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。
Output对于输入的每组数据,如果任意两个房间都是相互连接的,输出"Yes",否则输出"No"。
Sample Input

3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0

Sample Output

Yes
No
有一个坑点,以前0,0结束都是用cin>>n>>m,n,m处理的,结果这次不行,非要用
n==0&&m==0break;才ac,害我wa了好多遍
#include<map>
#include<set>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007

using namespace std;

const int N=10005,maxn=100005,inf=0x3f3f3f3f;

int n,m;//判断是不是在栈中,2为在栈中,1为已访问不在栈中,0为不在栈中
stack<int>s;
vector<int>v[N],ans[N];
int dfn[N],low[N];
int inans[N],ins[N];
int num,index;

void tarjan(int u)
{
    ins[u]=2;//u标记在栈中
    low[u]=dfn[u]=++index;//low,dfn计数
    s.push(u);//加入栈方便回溯找强连通分量
    for(int i=0;i<v[u].size();i++)//找u的连接点
    {
        int t=v[u][i];
        if(dfn[t]==0)//下一个点还没有被访问到
        {
            tarjan(t);//继续搜索
            low[u]=min(low[u],low[t]);
        }
        else if(ins[t]==2)low[u]=min(low[u],dfn[t]);//下一个点在栈中了
    }
    if(low[u]==dfn[u])
    {
        ++num;
        while(!s.empty()){
            int k=s.top();
            s.pop();
            ins[k]=1;
            ans[num].push_back(k);
            inans[k]=num;
            if(k==u)break;
        }
    }
}
int main()
{
    while(cin>>n>>m){
        if(n==0&&m==0)break;
        while(!s.empty())s.pop();
        for(int i=1;i<=n;i++)
        {
            v[i].clear();
            ans[i].clear();
        }
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(ins,0,sizeof(ins));
        memset(inans,0,sizeof(inans));
        num=index=0;
        while(m--){
            int a,b;
            cin>>a>>b;
            v[a].push_back(b);
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i])
               tarjan(i);
        if(num>1)cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
    }
    return 0;
}
/*
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
*/

 

posted @ 2017-03-31 20:42  walfy  阅读(289)  评论(0编辑  收藏  举报