1.题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1285
2.拓扑排序:
拓扑排序方法如下:
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边。
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止。
一般应用:
拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出一个线性的序列,则排在前面的任务就是需要先完成的任务。
3.参考代码:
#include <stdio.h>
#include <string.h>
int i,n,m,top; ///n为点数,m为边数
int edge[1100][1100]; ///图的邻接矩阵
int vis[1100]; ///标记是否访问过
int rudu[1100]; ///存入度的数量
void tuopu(){ ///拓扑算法
for(i=1;i<=n;i++) ///遍历所有点
{
if(!vis[i] && !rudu[i]) ///如果没有访问过,并且入度数为0,从小到大,号码小的优先
{
top=i; ///记录下标
vis[top]=1; ///标记为已访问过的
break; ///删除入度为0的点
}
}
for(i=1;i<=n;i++) ///遍历所有的点
{
if(edge[top][i]==1) ///相关联的点,入度减一
rudu[i]--;
}
}
int main()
{
int x,y;
while(~scanf("%d %d",&n,&m))
{
memset(rudu,0,sizeof(rudu)); ///初始化
memset(vis,0,sizeof(vis)); ///初始化
memset(edge,0,sizeof(edge)); ///初始化
for(i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
if(edge[x][y]!=1) ///考虑是否重边的情况
rudu[y]++;
edge[x][y]=1;
}
int l=n;
while(l--)
{
tuopu();
if(l==0)
printf("%d\n",top); ///注意格式的输出,最后一个数后面没有空格
else
printf("%d ",top);
}
}
return 0;
}