拓扑排序
对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
算法步骤
拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止:
(1) 选择一个入度为0的顶点并输出之。
(2) 从网中删除此顶点及所有出边。
循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。
例题
#include <stdio.h>
#include <string.h>
int a[505][505],b[505],ans[505];
int main()
{
int i,j,k,c,d,m,n,count;
while(scanf("%d%d",&m,&n)!=EOF)
{
count=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(ans,0,sizeof(ans));
for(i=1;i<=n;i++)
{
scanf("%d%d",&c,&d);
if(a[c][d]!=1)
{
a[c][d]=1;
b[d]++;
}
}
for(i=1;i<=m;i++)
{
for(j=1;j<=m;j++)
{
if(b[j]==0)
{
b[j]--;
ans[++count]=j;
for(k=1;k<=m;k++)
if(a[j][k]==1)
b[k]--;
break;
}
}
}
for(i=1;i<=count;i++)
{
if(i!=count)
printf("%d ",ans[i]);
else
printf("%d\n",ans[i]);
}
}
return 0;
}
#include <stdio.h>
#include <string.h>
int a[105][105],b[105];
int main()
{
int i,j,k,c,d,m,n;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m==0&&n==0)
break;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i=1;i<=n;i++)
{
scanf("%d%d",&c,&d);
if(a[c][d]!=1)
{
a[c][d]=1;
b[d]++;
}
}
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
if(b[j]==0)
{
b[j]--;
for(k=0;k<m;k++)
if(a[j][k]==1)
b[k]--;
break;
}
}
if(j==m)
break;
}
if(i==m)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}