题目链接:点击打开链接
题目大意:问你是否任意两个房间相通
题目思路:就是问你是否只存在一个强连通分量
dfn数组记录时间戳,vis表示是否在栈中,然后跑tarjan模板,num记录强联通分量个数,low==dfn就表示一个强联通分量,此时num++,最后判断num值即可
以下是代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define MAXN 100005
#define inf 0x3f3f3f3f
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
vector<int>g[MAXN];
int n,m,low[MAXN],dfn[MAXN],stack1[MAXN],top,cnt,num,vis[MAXN];
void tarjan(int u){
stack1[top++]=u;
vis[u]=1;
low[u]=dfn[u]=++cnt;
int len=g[u].size();
rep(i,0,len-1){
int v=g[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
num++;
int v;
do{
v=stack1[--top];
vis[v]=0;
}while(u!=v);
}
return;
}
int main(){
while(~scanf("%d%d",&n,&m)&&(n+m)){
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
rep(i,1,n) g[i].clear();
while(m--){
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
}
top=cnt=num=0;
rep(i,1,n){
if(!dfn[i]){
tarjan(i);
}
}
if(num==1){
printf("Yes\n");
}
else{
printf("No\n");
}
}
return 0;
}