拓扑排序 有向图回路的判断

拓扑排序与有向无环图的判断:
拓扑排序:把一个图的所有节点排序,使得每一条有向边(u,v)对应的u都排在v的前面。
总结
: 拓扑排序只在有向无环图中有效
:如果输入的有向图中的点,不存在入度为0的点,则该有向图存在回路,反过来则不成立
:如果存在的入度为0的点大于一个,则该有向图肯定不存在一个可以确定的拓扑序列但并不妨碍拓扑排序
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
访问完一个节点之后把它加到当前拓扑序的首部

1 int c[Maxn];
2 int topo[Maxn],t;
3 bool dfs(int u)
4 {
5 c[u]=-1;//u点正在被访问
6 for(int v=0;v<n;v++)if(G[u][v])
7 {
8 if(c[v]<0)returnfalse;//存在有向环,失败退出
9 elseif(!c[v]&&!dfs(v))returnfalse;//如果该点已经被访问过则不进行dfs的操作
10 }
11 c[u]=1;topo[--t]=u;
12 returntrue;
13 }
14 bool toposort()
15 {
16 t=n;
17 memset(c,0,sizeof(c));
18 for(int u=0;u<n;u++)if(!c[u])
19 if(!dfs(u))returnfalse;
20 returntrue;
21 }
22 c[u]=0从来没有访问过
23 c[u]=-1正在访问
24 c[u]=1已经访问

------------------------------------------
------------------------------------------
非递归算法 借一个典型例题的做法体现该算法

用到了有向无环图的判断和非递归形式的拓扑排序
poj 1094

1 #include<iostream>
2 #include<queue>
3 #define Maxn 27
4 usingnamespace std;
5 bool G[Maxn][Maxn],vis[Maxn],mark[Maxn];
6 int n,m,x,y,t,tmp,cnt,sum,indegree[Maxn],indegrees[Maxn],flag;
7 char cx,cy,ct,ans[Maxn];
8 int toposort()
9 {
10 for(int i=0;i<n;i++)
11 indegree[i]=indegrees[i];
12 memset(vis,false,sizeof(vis));
13 cnt=0;
14 queue<int>q;
15 for(int i=0;i<n;i++)
16 {
17 if(mark[i]&&indegree[i]==0)
18 {
19 vis[i]=1;
20 q.push(i);
21 }
22 }
23 if(q.empty())return-1;
24 if(q.size()>1)flag=1;//证明存在不确定的序列
25 int loc=0;
26 while(!q.empty())
27 {
28 tmp=q.front();
29 q.pop();
30 cnt++;//记录入队的元素个数
31 ans[loc++]=tmp+'A';
32 int cot=0;//用于记录入度为零的点的个数
33 for(int i=0;i<n;i++)if(G[tmp][i])//如果图中存在该点
34 {
35 indegree[i]--;
36 if(!indegree[i]&&!vis[i])//如果入度为0并且没有被访问过
37 {
38 vis[i]=1;
39 q.push(i);
40 cot++;
41 }
42 }
43 if(q.empty()&&cnt!=sum)
44 {
45 return-1;
46 }
47 if(cot>1)flag=1;//如果存在多个入度为零的点则不能确定序列
48 }
49 ans[loc]='\0';
50 return cnt;
51 }
52 int main()
53 {
54 while(cin>>n>>m)
55 {
56 if(n==0&&m==0)
57 break;
58 sum=0;//标记是否存在确定的序列
59 memset(G,false,sizeof(G));
60 memset(mark,false,sizeof(mark));
61 memset(indegrees,0,sizeof(indegree));
62 int nocontinue=0;
63 for(int i=1;i<=m;i++)
64 {
65 cin>>cx>>ct>>cy;
66 if(nocontinue==1)
67 continue;
68 flag=0;
69 x=cx-'A';
70 y=cy-'A';
71 G[x][y]=true;
72 if(!mark[x]) mark[x]=true,sum++;
73 if(!mark[y]) mark[y]=true,sum++;
74 indegrees[y]++;
75 t=toposort();
76 if(t==-1)
77 {
78 nocontinue=1;
79 cout<<"Inconsistency found after "<<i<<" relations."<<endl;
80 }
81 if(flag==0&&t==n)//如果入队的元素个数与输入的元素个数一致并且可以唯一确定序列则有解
82 {
83 nocontinue=1;
84 cout<<"Sorted sequence determined after "<<i<<" relations: "<<ans<<"."<<endl;
85 }
86 }
87 if(!nocontinue)
88 cout<<"Sorted sequence cannot be determined."<<endl;
89 }
90 system("pause");
91 return0;
92 }
93 /*
94 4 6
95 A<B
96 A<C
97 B<C
98 C<D
99 B<D
100 A<B
101 3 2
102 A<B
103 B<A
104 26 1
105 A<Z
106 0 0
107 */

 

posted @ 2011-03-02 15:49  Penseur  阅读(4613)  评论(0编辑  收藏  举报