
这一题的意思是完成某项工作的前提是先完成另一项工作,给出部分先后顺序,判断出全部工作完成的顺序,可能会有多个答案,输出一个即可。
例如 有5个工作
有4个部分顺序,1在2的前面,2在3的前面,1在3的前面,1在5的前面。
可知1、2、3的先后顺序不变,1、5的先后顺序不变,中间可以插其他的元素,
而4可以放在任意位置。
这一题就是一个拓扑排序,将前面带有限定元素的标记起来,每有一个就加一。每次当它前面的限定元素输出后就减一,直到为0后输出。
#include<stdio.h>
#include<string.h>
int n,m,book[1010][1010];
struct w
{
int x,y;
}s[1010];
int main()
{
while(~scanf("%d%d",&n,&m)&&n+m)
{
int a,b;
memset(s,0,sizeof(s));
memset(book,0,sizeof(book));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
if(book[a][b]==0)
{
book[a][b]=1;//将它们的关系用二维数组标记起来,当a出列,此时b才有可能出列
s[b].x++;//将所有的要往后排的数字标记起来,没被标记的可以优先出列,只有s[b].x==0,即它前面的数全部出列,b才能出列。
}
}
int k,l=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[j].x==0)
{
k=j;//标记此时可以出列的序号
break;
}
}
s[l++].y=k;//将可以出列的序号存入数组中
s[k].x=-1;//将已经找到的数标记起来,防止再次寻找
for(int j=1;j<=n;j++)
{
if(book[k][j]==1)//找到已经出列的数的后面的数
{
s[j].x--;//将已经出列的数解除对后面数的压制
}
}
}
for(int i=0;i<l;i++)
{
if(i<l-1)
printf("%d ",s[i].y);
else
printf("%d\n",s[i].y);
}
}
return 0;
}
该博客讨论了如何利用拓扑排序解决一项任务的完成依赖于其他任务的问题。通过给出的示例,解释了在5个工作中,4个部分顺序如何定义了任务的前后关系。博主提出,这种情况下可以通过标记和计数依赖来确定所有任务的可能顺序,并强调拓扑排序在这种场景中的应用。
&spm=1001.2101.3001.5002&articleId=97537942&d=1&t=3&u=c329823d23854c5a944eb9719d3c6dff)
259

被折叠的 条评论
为什么被折叠?



