数据结构实验之图论十:判断给定图是否存在合法拓扑序列
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。
Input
输入包含多组,每组格式如下。
第一行包含两个整数n,m,分别代表该有向图的顶点数和边数。(n<=10)
后面m行每行两个整数a b,表示从a到b有一条有向边。
Output
若给定有向图存在合法拓扑序列,则输出YES;否则输出NO。
Sample Input
1 0
2 2
1 2
2 1
Sample Output
YES
NO
Hint
Source
赵利强
合法就是没有回路;如果有回路,由于回路中的点入度都不是0,那么最后图中肯定还会有剩余的点;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
using namespace std;
queue<int>q;
int book[101],e[101][101],n;
int p[101];
void topsort()
{
int cnt=0;
for(int i=1;i<=n;i++)
{
if(p[i]==0)
{
q.push(i);
}
}//先把入度为0的点放入一个队
while(!q.empty())
{
int u=q.front();
q.pop();
book[u]=1;//出队就标记一下;
cnt++;//记录下入队的点的个数,为了与后面的n比较,判断回路;
for(int i=1;i<=n;i++)
{
if(e[u][i]==1&&book[i]==0)//把与他相连的点的入度都减少1;
{
if(--p[i]==0)//入度为0了再入队;
{
q.push(i);
}
}
}
}
if(cnt!=n)printf("NO\n");
else printf("YES\n");
}
int main()
{
int m;
while(~scanf("%d%d",&n,&m))
{
memset(p,0,sizeof(p));
memset(book,0,sizeof(book));
memset(e,0,sizeof(e));
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u][v]=1;
p[v]++;
}
if(m==0)printf("YES\n");//没有边就说明没有回路
else
topsort();
}
return 0;
}