数据结构实验之图论十:判断给定图是否存在合法拓扑序列
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main()
{
int n,m,a[20][20],book[20],dp[20]; //a记录边,book几率删除的点,dp记录指向这个点的边数
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(book,0,sizeof(book));
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
int i,j,k,s=n; //s记录能删除的点数
for(i=0; i<m; i++)
{
int q,w;
scanf("%d%d",&q,&w);
a[q][w]=1; //记录边
dp[w]++; //记录指向这个点的边数
}
for(i=0; i<n; i++) //遍历n次
{
for(j=1; j<=n; j++)
{
if(book[j]==0&&dp[j]==0) //找可以删除的点,指向这个点的边为0
{
book[j]=1; //记录删除
s--; //删除一个点
for(k=1; k<=n; k++)
{
if(a[j][k]==1) //找删除的这个点指向其它点的边,进行删除
{
dp[k]--; //删除指向这个点的一条边,因为刚刚那个点被删除了
}
}
break; //如果删除了一个点,就跳出这个循环,进行下一次遍历
}
}
}
if(!s)printf("YES\n"); //如果s==0说明删除完了,说明存在拓扑序列
else printf("NO\n"); //否则,则不存在
}
return 0;
}