拓扑入门 poj2367 Genealogical tree

                 这是道赤裸裸的拓扑排序题

   先不说这道题  ,首先要知道拓扑排序的概念,其实就是把入度为0 的点输出来 ,入度为零????什麽意思。。

顾名思义,入度为0指有向图中的点不作为任何边的终点,也就是说,这一点所连接的边都把这一点作为起点。
在有向图的拓扑排序中,每次都选取入度为0的点加入拓扑队列中,再删除与这一点连接的所有边。
其实也就是说,如图
c0,c1,入度为零,输出之后删除有向边c0->c2,c1->c2,那么c2,c4,c7的入度为零,以此类推输出序列为c0,c1,c2,c4,c7,c3,c8,c5,c7;
此题中的就看测试数据
0
4 5 1 0
1 0
5 3 0
3 0
可知1后面什么也没有,2后面有4,5,1;3后面有1;4后面有5,3;5后面有3;
即上图 拓扑入门 poj2367 Genealogical tree_第1张图片
可得出序列为2 ->4->5->3->1;
具体代码实现如下
   
   
   
   
#include <stdio.h>
#include <string.h>
int main()
{
int d[101];//记录入度
int vis[101][101];//标记i指向j的边
int r[101];//记录结果
int n,m;
int i,j;
int k,x;
while(scanf("%d",&n)==1)
{
memset(d,0,sizeof(d));//初始化
memset(vis,0,sizeof(vis));//一定要初始化当时就没有初始化,小细节,一定要注意
for(i=1;i<=n;i++)
{
while(scanf("%d",&x),x)
{
vis[i][x]=1;//标记
d[x]++;// 记录入度
}
}
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(d[j]==0)
{
k=j;//找出标记
break;
}
}
d[k]=-1;//标记不被找出
r[i]=k;
for(j=1; j<=n; j++)
if(vis[k][j])//如果存在这个边,找出并删除
d[j]--;
}
for(i=1;i<n;i++)
printf("%d ",r[i]);
printf("%d\n",r[n]);
}
return 0;
}


你可能感兴趣的:(c,拓扑,poj)