图论之各种找环

给我们一个有向图,找出长度为3的环,如果有的话,输出环上的三个点,如果没有,输出-1

因为只有三个点,所以可以暴力, 枚举两条边,判断第三条是不是存在即可。  fa -> u, u -> i,    判断g[i][fa]==1?

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <string.h>
 5 #include <math.h>
 6 #include <vector>
 7 #include <string>
 8 #include <vector>
 9 #include <set>
10 #include <map>
11 #include <queue>
12 #include <stack>
13 #include <algorithm>
14 #include <functional>
15 using namespace std;
16 
17 const int N = 5000 + 10;
18 char g[N][N];
19 bool vis[N];
20 int n;
21 int a,b,c;
22 void dfs(int u, int fa)
23 {
24     vis[u] = true;
25     for(int i=1; i<=n&&(!a||!b||!c);++i)
26     {
27         if(g[u][i]==0) continue;
28         if(fa!=-1 && g[i][fa]==1)
29         {
30             a = fa;
31             b = u;
32             c = i;
33         }
34         if(!vis[i])
35             dfs(i,u);
36     }
37 }
38 int main()
39 {
40 
41     while(scanf("%d",&n)!=EOF)
42     {
43         for(int i=1;i<=n;++i)
44         {
45             scanf("%s",g[i]+1);
46             for(int j=1;j<=n;++j)
47                 g[i][j] -= '0';
48 
49         }
50         memset(vis,0,sizeof(vis));
51         a = b = c = 0;
52         for(int i=1;i<=n;++i)
53             if(!vis[i])
54                 dfs(i,-1);
55         if(!a)
56             printf("%d\n",-1);
57         else
58             printf("%d %d %d\n",a,b,c);
59 
60     }
61     return 0;
62 }
View Code

 

有向图找出所有的环,并输出(找的同时就能判断是奇偶环,也能找到最大的环)

利用是否存在后向边来判断,

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <string.h>
 5 #include <math.h>
 6 #include <vector>
 7 #include <string>
 8 #include <vector>
 9 #include <set>
10 #include <map>
11 #include <queue>
12 #include <stack>
13 #include <algorithm>
14 #include <functional>
15 using namespace std;
16 
17 const int N = 5000 + 10;
18 vector<int> g[N];
19 int st[N],instack[N],mark[N],top;
20 void dfs(int u)
21 {
22     instack[u] = true;
23     mark[u] = true;//因为可能不联通,所以需要没有mark过的点,需要再次调用dfs
24     st[++top] = u;
25     for(int i=0;i<g[u].size(); ++i)
26     {
27         int v = g[u][i];
28         if(!instack[v])
29             dfs(v);
30         else
31         {
32 
33             int t;
34             for(t=top;st[t]!=v;--t);//在栈中找到环的起始点
35             printf("%d:",top-t+1);//这这里就能判断是奇数环还是偶数环
36             for(int j=t;j<=top;++j)
37                 printf("%d ",st[j]);
38             puts("");
39         }
40     }
41     instack[u] = false;
42     top--;
43 }
44 void init(int n)
45 {
46     for(int i=1;i<=n;++i)
47     {
48         g[i].clear();
49         instack[i] = mark[i] = 0;
50     }
51     top = 0;
52 }
53 int main()
54 {
55     int n,m;
56     while(scanf("%d%d",&n,&m)!=EOF)
57     {
58         init(n);
59         int u,v;
60         for(int i=1;i<=m;++i)
61         {
62             scanf("%d%d",&u,&v);
63             g[u].push_back(v);
64         }
65         for(int i=1;i<=n;++i)
66             if(!mark[i])
67                 dfs(i);
68     }
69     return 0;
70 }
View Code

 

各种找环

START————————————————————————

无向图判断是否存在环

topoSort变种,将度<=1的点入队列,如果最后没有将所有的点入过队列,那么久存在环

无向图找长度为奇数或者长度为偶数的环。

首先,我们找到所有的点双联通分量,那么每个分量里面的点都在环上。那么而判断环是奇环还是偶环可以用二分图染色来判断,如果是奇环,那么肯定不是二分图,反之是偶环。

 

有向图判断是否存在环

即判断是否是dag,可以用topoSort,复杂度O(E),也可以用dfs,如果存在后向边,那么就存在环,如果当前点有指向在栈中结点的边,那么就是后向边。

有向图找出所有的环并输出,能找到最大环,也能判断奇偶环

 

posted @ 2015-09-17 17:46  justPassBy  阅读(2614)  评论(1编辑  收藏  举报