Description
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。
Input
输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)
后面m行每行两个整数a b,表示从a到b有一条有向边。
Output
若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。
Sample
Input
1 0
2 2
1 2
2 1
Output
YES
NO
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
bool Map[11][11],vis[11];
int indegree[11];
int n,m;
//求入度
void CountIndegree()
{
memset(indegree,0,sizeof(indegree));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(Map[j][i])
indegree[i]++;
}
}
//拓扑排序
bool TopoSort()
{
int x;
int Count = 0;
//记录删掉点的个数
CountIndegree();
//利用栈实现
stack<int> s;
//入度为0,入栈
for(int i=1;i<=n;i++)
{
if(indegree[i] == 0)
s.push(i);
}
while(!s.empty())
{
x = s.top();
s.pop();
Count++;
//删除以x为起点相关边
for(int i=1;i<=n;i++)
{
if(Map[x][i])
{
//i的入度--
indegree[i]--;
if(indegree[i] == 0)
s.push(i);
}
}
}
//if(count < n),有环
if(Count < n)
return false;
else
return true;
}
int main()
{
ios::sync_with_stdio(false);
int u,v;
while(cin>>n>>m)
{
memset(Map,false,sizeof(Map));
for(int i=0;i<m;i++)
{
cin>>u>>v;
Map[u][v] = true;
}
if(TopoSort())
cout<<"YES\n";
else
cout<<"NO\n";
}
return 0;
}