拓扑序列的判断方法为不存在有向环,代码实现的话有两种,一种是直接去判断是否存在环,较为难理解一些,另一种的话去判断结点入度,如果存在的入度为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 }
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 }