题目描述
给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。
输入
输入包含多组,每组格式如下。
第一行包含两个整数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之前。
通常,这样的线性序列称为满足拓扑次序(TopoiSicai Order)的序列,简称拓扑序列。
把所有入度为0的点入队列,依次弹出,若某一点弹出,则把该点到达大下一个点的入度-1,在遍历一下若有入度为0的点继续入队列,重复上个操作,若该循环结束,假如弹出点为n个则 是拓扑,否则,不是。
通常,这样的线性序列称为满足拓扑次序(TopoiSicai Order)的序列,简称拓扑序列。
把所有入度为0的点入队列,依次弹出,若某一点弹出,则把该点到达大下一个点的入度-1,在遍历一下若有入度为0的点继续入队列,重复上个操作,若该循环结束,假如弹出点为n个则 是拓扑,否则,不是。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
}*head[20];
int degree[20];
int st[20];
int dis[20];
int main()
{
int i,a,b,cnt;
int n,m;
struct node *p;
for( i = 0; i < 20; i++ )
{
head[i] = (struct node *)malloc(sizeof(struct node));
}
while( ~scanf("%d %d",&n,&m) )
{
int top = 0;
cnt = 0;
for( i = 0; i <= n; i++ )
{
head[i]->next = NULL;
}
memset(degree,0,sizeof(degree));
memset(dis,0,sizeof(dis));
for( i = 0; i < m; i++ )
{
scanf("%d %d",&a,&b);
p = (struct node *)malloc(sizeof(struct node));
p->data = b;
p->next = head[a]->next;
head[a]->next = p;
degree[b]++;
}
for( i = 1; i <= n; i++ )
{
if( degree[i] == 0 )
{
dis[i] = 1;
st[++top] = i;
}
}
while( top )
{
int t = st[top--];
cnt++;
p = head[t]->next;
while( p )
{
degree[p->data]--;
p = p->next;
}
for( i = 1; i <= n; i++ )
{
if( !dis[i] && degree[i] == 0 )
{
dis[i] = 1;
st[++top] = i;
}
}
}
if( cnt < n )
{
printf("NO\n");
}
else
{
printf("YES\n");
}
}
return 0;
}