迷宫城堡(强联通targin)
迷宫城堡
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10409 Accepted Submission(s): 4674
Problem Description
为
了训练小希的方向感,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
题解:
强联通问题,targin算法,或者dfs做,建图也可以用邻接表,或者vector;
方法一dfs:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define MAX(x,y)(x>y?x:y) 8 #define MIN(x,y)(x<y?x:y) 9 //#define LOCAL 10 const int INF=0x3f3f3f3f; 11 const int MAXN=10010; 12 vector<int>vec[MAXN]; 13 int vis[MAXN]; 14 void dfs(int x){ 15 for(int i=0;i<vec[x].size();i++){ 16 int v=vec[x][i]; 17 if(vis[v])continue; 18 vis[v]=1; 19 dfs(v); 20 } 21 } 22 int main(){ 23 #ifdef LOCAL 24 freopen("data.in","r",stdin); 25 freopen("data.out","w",stdout); 26 #endif 27 int N,M; 28 while(~scanf("%d%d",&N,&M),N|M){ 29 for(int i=0;i<MAXN;i++)vec[i].clear(); 30 while(M--){ 31 int a,b; 32 scanf("%d%d",&a,&b); 33 vec[a].push_back(b); 34 } 35 int ans=1; 36 for(int i=1;i<=N;i++){ 37 memset(vis,0,sizeof(vis)); 38 vis[i]=1; 39 dfs(i); 40 for(int i=1;i<=N;i++){ 41 if(vis[i]==0){ 42 ans=0; 43 break; 44 } 45 if(!ans)break; 46 } 47 if(!ans)break; 48 } 49 if(ans)puts("Yes"); 50 else puts("No"); 51 } 52 return 0; 53 }
方法二:targin算法:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<stack> 7 #include<vector> 8 #define mem(x,y) memset(x,y,sizeof(x)) 9 using namespace std; 10 const int INF=0x3f3f3f3f; 11 const int MAXN=10010; 12 //#define LOCAL 13 vector<int>vec[MAXN]; 14 stack<int>S; 15 int dfn[MAXN],low[MAXN],Instack[MAXN]; 16 int scc,dfs_block; 17 void targin(int u,int fa){ 18 dfn[u]=low[u]=++dfs_block; 19 S.push(u); 20 Instack[u]=1; 21 for(int i=0;i<vec[u].size();i++){ 22 int v=vec[u][i]; 23 if(!dfn[v]){ 24 targin(v,u); 25 low[u]=min(low[u],low[v]); 26 } 27 else if(Instack[v]) 28 low[u]=min(low[u],dfn[v]); 29 } 30 if(low[u]==dfn[u]){ 31 scc++; 32 while(1){ 33 int v=S.top(); 34 S.pop(); 35 Instack[v]=0; 36 if(u==v)break; 37 } 38 } 39 } 40 int main(){ 41 #ifdef LOCAL 42 freopen("data.in","r",stdin); 43 freopen("data.out","w",stdout); 44 #endif 45 int N,M; 46 while(~scanf("%d%d",&N,&M),N|M){ 47 for(int i=0;i<MAXN;i++)vec[i].clear(); 48 mem(dfn,0);mem(low,0);mem(Instack,0); 49 while(!S.empty())S.pop(); 50 int a,b; 51 while(M--){ 52 scanf("%d%d",&a,&b); 53 vec[a].push_back(b); 54 } 55 scc=dfs_block=0; 56 for(int i=1;i<=N;i++){ 57 if(dfn[i])continue; 58 targin(i,-1); 59 } 60 if(scc==1)puts("Yes"); 61 else puts("No"); 62 } 63 return 0; 64 }
邻接表建图又写了一遍,邻接表都不太熟练了:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<stack> 7 #include<vector> 8 using namespace std; 9 const int INF=0x3f3f3f3f; 10 //#define LOCAL 11 #define mem(x,y) memset(x,y,sizeof(x)) 12 const int MAXN=10010; 13 const int MAXM=100010;//<<1; 14 int head[MAXM],low[MAXN],dfn[MAXN],Instack[MAXN]; 15 int edgnum,dfs_block,lcc; 16 stack<int>S; 17 struct Edge{ 18 int from,to,next; 19 }; 20 Edge edg[MAXM]; 21 void add(int u,int v){ 22 Edge E={u,v,head[u]}; 23 edg[edgnum]=E; 24 head[u]=edgnum++;//** 25 } 26 void targin(int u,int fa){ 27 low[u]=dfn[u]=++dfs_block; 28 S.push(u); 29 Instack[u]=1; 30 for(int i=head[u];i!=-1;i=edg[i].next){//** 31 int v=edg[i].to; 32 if(!dfn[v]){ 33 targin(v,u); 34 low[u]=min(low[v],low[u]); 35 } 36 else if(Instack[v]){ 37 low[u]=min(low[u],dfn[v]); 38 } 39 } 40 if(low[u]==dfn[u]){ 41 lcc++; 42 while(1){ 43 int v=S.top(); 44 S.pop(); 45 Instack[v]=0; 46 if(u==v)break; 47 } 48 } 49 } 50 int main(){ 51 #ifdef LOCAL 52 freopen("data.in","r",stdin); 53 freopen("data.out","w",stdout); 54 #endif 55 int N,M; 56 while(~scanf("%d%d",&N,&M),N|M){ 57 mem(head,-1);mem(dfn,0);mem(low,0);mem(Instack,0); 58 edgnum=dfs_block=lcc=0; 59 while(!S.empty())S.pop(); 60 int a,b; 61 while(M--){ 62 scanf("%d%d",&a,&b); 63 add(a,b); 64 } 65 for(int i=1;i<=N;i++){ 66 if(dfn[i])continue; 67 targin(i,-1); 68 } 69 if(lcc==1)puts("Yes"); 70 else puts("No"); 71 } 72 return 0; 73 }