您的位置:首页 > 其它

图结构练习——判断给定图是否存在合法拓扑序列

2015-08-14 16:25 323 查看

题目描述

 给定一个有向图,判断该有向图是否存在一个合法的拓扑序列。

输入

 输入包含多组,每组格式如下。
第一行包含两个整数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个则 是拓扑,否则,不是。

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: