现在的位置: 首页 > 综合 > 正文

hdu1285确定比赛名次

2013年07月25日 ⁄ 综合 ⁄ 共 1017字 ⁄ 字号 评论关闭

1.题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1285

 

2.拓扑排序:

拓扑排序方法如下:
(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它。
(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;
}

抱歉!评论已关闭.