拓扑序列的判断方法为不存在有向环,代码实现的话有两种,一种是直接去判断是否存在环,较为难理解一些,另一种的话去判断结点入度,如果存在的入度为0的点大于一个,则该有向图肯定不存在一个确定的拓扑序列

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cstdlib>
 5 using namespace std;
 6 int vis[11];
 7 int m,n,u,v;
 8 int map[11][11];
 9 int dfs(int u)
10 {
11     vis[u]=-1;//正在访问
12     for(v=1; v<=m; v++)
13     {
14         if(map[u][v])
15         {
16             if(vis[v]<0)
17                 return 0;//去掉自环
18             else if(!vis[v]&&!dfs(v))//v元素还没有被访问而且v的后继元素和前面的正在访问的元素构成了回路(构成的回路不是自回路的情况)。
19                 return 0;
20         }
21     }
22     vis[u]=1;
23     return 1;
24 
25 }
26 int toposort()
27 {
28     for(u=1; u<=m; u++)
29     {
30         if(!vis[u])
31         {
32             if(!dfs(u))
33                 return 0;
34         }
35     }
36     return 1;
37 
38 }
39 int main()
40 {
41     while(~scanf("%d %d",&m,&n)&&(m+n!=0))
42     {
43         memset(vis,0,sizeof(vis));
44         memset(map,0,sizeof(map));
45         for(int i=0; i<=n-1; i++)
46         {
47             scanf("%d %d",&u,&v);
48             map[u][v]=1;
49         }
50         if(toposort())
51             cout<<"YES"<<endl;
52         else cout<<"NO"<<endl;
53     }
54     return 0;
55 }
View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<iostream>
 5 using namespace std;
 6 int map[51][51],count[51];
 7 int flag;
 8 int u,v,vis;
 9 int main()
10 {
11     int m,n;
12     //memset(map,0,sizeof(map));
13     //memset(count,0,sizeof(count));
14     while(~scanf("%d %d",&m,&n)&&(n!=0||m!=0))
15     {
16         memset(map,0,sizeof(map));
17     memset(count,0,sizeof(count));//每个节点的入度初始为0;
18         vis=0;//标记变量,用于帮助最后输出
19         for(int i=0; i<=n-1; i++)
20         {
21             scanf("%d %d",&u,&v);
22             map[u][v]=1;
23             count[v]++;
24         }
25         for(int i=0; i<=m-1; i++)
26         {
27             int flag=0;
28             for(u=1; u<=m; u++)
29             {
30                 if(count[u]==0)
31                 {
32                     flag=1;//只要有入度为0的点就变为1
33                     count[u]--;//删除掉这个节点
34                     for(v=1; v<=m; v++)//凡是与该节点有关的所有结点入度去掉1;
35                     {
36                         if(map[u][v])
37                         {
38                             count[v]--;
39                         }
40                     }
41                     break;
42                 }
43             }
44             if(flag==0)//如果没有入度为0的点,就代表没有拓扑序列
45             {
46                    vis=1;
47                    break;
48             }
49         }
50         if(vis==0)
51         cout<<"YES"<<endl;
52         else cout<<"NO"<<endl;
53     }
54     return 0;
55 }
View Code

 

posted on 2013-07-29 15:52  枫、  阅读(703)  评论(2编辑  收藏  举报