sdut 2497 A simple problem (并查集 or dfs)

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: 并查集 :

  若   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 }

 

你可能感兴趣的:(simple)