http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2497
题意 : 给定一个 无向图 和 一个点 s 求 是否 图中的 所有环 都包含 点s (保证 图中 至少 有 一个环)
题解 : dfs 求解 只要 搜到 一个 被访问过的点 而且这个点 不是 s 那么 就有环 不含有 s
View Code
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define inf 99999999
12 #define maxn 15000
13 #define CL(a,b) memset(a,b,sizeof(a))
14 #define ll long long
15 //#define mx 1000010
16 using namespace std;
17 int n, m ,s;
18 struct node
19 {
20 int from ;
21 int to ;
22 int next ;
23 }p[maxn*20] ;
24 int head[maxn] ;
25 int cnt ;
26 void add(int u,int v)
27 {
28 p[cnt].from = u;
29 p[cnt].to = v;
30 p[cnt].next = head[u] ;
31 head[u] = cnt++ ;
32 }
33 int f ;
34 int vis[maxn] ;
35 int num ;
36 void dfs(int x,int fa)
37 {
38 vis[x] = ++num ;// 时间 戳
39 if(f) return ;
40 for(int i = head[x];i!= -1 ;i = p[i].next)
41 {
42 int to = p[i].to ;
43
44 if(to == fa)continue ;
45 if(vis[to])
46 {
47 if(to != s && vis[to] < vis[x])// 一个 被访问了的点 ,不是 s 而且 这个点的时间戳 早于 本身
48 {
49
50
51 f = 1 ;
52 return ;
53
54 }
55 else continue ;
56
57
58 }
59 else
60 {
61
62 dfs(to,x) ;
63 }
64
65
66
67 }
68 }
69 int main()
70 {
71 int i ,a,b;
72 while(scanf("%d%d%d",&n,&m,&s)!=EOF)
73 {
74 cnt = 0 ;
75 CL(head,-1) ;
76 for(i = 0; i < m;i++)
77 {
78 scanf("%d%d",&a,&b) ;
79 add(a,b);
80 add(b,a);
81
82 }
83
84 CL(vis,0) ;
85 f = 0 ;
86 num = 0 ;
87 dfs(s,-1) ;
88
89
90 if(f)printf("NO\n");
91 else printf("YES\n") ;
92 }
93 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define inf 99999999
12 #define maxn 15000
13 #define CL(a,b) memset(a,b,sizeof(a))
14 #define ll long long
15 //#define mx 1000010
16 using namespace std;
17 int n, m ,s;
18 struct node
19 {
20 int from ;
21 int to ;
22 int next ;
23 }p[maxn*20] ;
24 int head[maxn] ;
25 int cnt ;
26 void add(int u,int v)
27 {
28 p[cnt].from = u;
29 p[cnt].to = v;
30 p[cnt].next = head[u] ;
31 head[u] = cnt++ ;
32 }
33 int f ;
34 int vis[maxn] ;
35 int num ;
36 void dfs(int x,int fa)
37 {
38 vis[x] = ++num ;// 时间 戳
39 if(f) return ;
40 for(int i = head[x];i!= -1 ;i = p[i].next)
41 {
42 int to = p[i].to ;
43
44 if(to == fa)continue ;
45 if(vis[to])
46 {
47 if(to != s && vis[to] < vis[x])// 一个 被访问了的点 ,不是 s 而且 这个点的时间戳 早于 本身
48 {
49
50
51 f = 1 ;
52 return ;
53
54 }
55 else continue ;
56
57
58 }
59 else
60 {
61
62 dfs(to,x) ;
63 }
64
65
66
67 }
68 }
69 int main()
70 {
71 int i ,a,b;
72 while(scanf("%d%d%d",&n,&m,&s)!=EOF)
73 {
74 cnt = 0 ;
75 CL(head,-1) ;
76 for(i = 0; i < m;i++)
77 {
78 scanf("%d%d",&a,&b) ;
79 add(a,b);
80 add(b,a);
81
82 }
83
84 CL(vis,0) ;
85 f = 0 ;
86 num = 0 ;
87 dfs(s,-1) ;
88
89
90 if(f)printf("NO\n");
91 else printf("YES\n") ;
92 }
93 }
题解2: 并查集 :
若 s 包含在所有的 环中 那么 去掉 与 s 相关联的 边 之后 图中 一定 没有 环 ,否则, s 不包含在 所有的环中。
View Code
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define inf 99999999
12 #define maxn 15000
13 #define CL(a,b) memset(a,b,sizeof(a))
14 #define ll long long
15 //#define mx 1000010
16 using namespace std;
17 int n, m ,s;
18 int f[maxn] ;
19 int find(int x)
20 {
21 if(x != f[x]) f[x] = find(f[x]) ;
22 return f[x] ;
23 }
24 int main()
25 {
26 int i, a,b ;
27 while(scanf("%d%d%d",&n,&m,&s)!=EOF)
28 {
29 for(i = 0; i <=n;i++)
30 {
31 f[i] = i ;
32
33 }
34 int flag = 0 ;
35 while(m --)
36 {
37 scanf("%d%d",&a,&b);
38 if(a == s|| b == s)continue ;
39
40 int x = find(a);
41 int y = find(b) ;
42 if(x == y) flag = 1 ;
43 else
44 {
45 f[x] = y;
46
47 }
48 }
49 if(flag == 1) printf("NO\n");
50 else printf("YES\n") ;
51 }
52 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define inf 99999999
12 #define maxn 15000
13 #define CL(a,b) memset(a,b,sizeof(a))
14 #define ll long long
15 //#define mx 1000010
16 using namespace std;
17 int n, m ,s;
18 int f[maxn] ;
19 int find(int x)
20 {
21 if(x != f[x]) f[x] = find(f[x]) ;
22 return f[x] ;
23 }
24 int main()
25 {
26 int i, a,b ;
27 while(scanf("%d%d%d",&n,&m,&s)!=EOF)
28 {
29 for(i = 0; i <=n;i++)
30 {
31 f[i] = i ;
32
33 }
34 int flag = 0 ;
35 while(m --)
36 {
37 scanf("%d%d",&a,&b);
38 if(a == s|| b == s)continue ;
39
40 int x = find(a);
41 int y = find(b) ;
42 if(x == y) flag = 1 ;
43 else
44 {
45 f[x] = y;
46
47 }
48 }
49 if(flag == 1) printf("NO\n");
50 else printf("YES\n") ;
51 }
52 }