图结构练习——判断给定图是否存在合法拓扑序列
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。
输入
输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)
后面m行每行两个整数a b,表示从a到b有一条有向边。
输出
若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。
示例输入
1 0 2 2 1 2 2 1
示例输出
YES NO 注: 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列 中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作 称之为拓扑排序。 方法一(参考网上的题解)#include<bits/stdc++.h> using namespace std; int main() { int f,n,m,i,j,k,a,b; while (cin>>n>>m) { int v[20]={0},mp[20][20]={0},vis[20]={0}; for (i=1;i<=m;i++) { cin>>a>>b; mp[a][b]=1; v[b]++; } for (i=1;i<=n;i++) { f=0; for (j=1;j<=n;j++) { if (!v[j]&&!vis[j]) { vis[j]=1; for (k=1;k<=n;k++) { if (mp[j][k]==1) { v[k]--; } } f=1; break; } } if (f==0) break; } if (!f) cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0; }
方法二(利用队列,主体思想同法一是一致的)#include<bits/stdc++.h> using namespace std; int v[101],mp[101][101]; int n,m; bool topo() { int s=0,i; queue<int> q; for (i=1;i<=n;i++) { if (v[i]==0) { q.push(i); v[i]=-1; } } while (!q.empty()) { int p=q.front(); q.pop(); s++; for (i=1;i<=n;i++) { if (mp[p][i]==1) { v[i]--; if (v[i]==0) { q.push(i); v[i]=-1; } } } } return s==n; } int main() { int a,b,i; while (cin>>n>>m) { memset(v,0,sizeof(v)); memset(mp,0,sizeof(mp)); for (i=0;i<m;i++) { cin>>a>>b; mp[a][b]=1; v[b]++; } printf("%s\n",topo()?"YES":"NO"); } return 0; }