迷宫城堡(强联通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 }

 

posted @ 2015-10-21 17:42  handsomecui  阅读(652)  评论(0编辑  收藏  举报