码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1285 确定比赛名次(拓扑排序模板)

时间:2014-08-06 10:38:51      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:style   color   os   io   strong   for   ar   代码   

题意还是比较容易理解的,关键要看到后面的:合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;

思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了。

拓扑排序:

拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前。
所以我们的算法可以描述为这样一个过程:
1、找到整个图中所有的度为0的点,将这些点压进队列(栈)中
2、从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删除指向它的点后),则压入队列(栈)
3、重复2过程,直到它为空

注:所谓度为0,即没有子节点,为1则只有一个,为2则有2个。为什么要先让度为0的点出来?因为你在定义的时候,度为0的点,则说明其没有父节点,即没有人排在它的前面!

所以基本AC代码:
#include<iostream>
#include<cstring>
using namespace std;
int map[502][502],flag[502],m,n,val[502];
void topsort()
{
	int i, j, k=1;
	for(i=1; i<=n; i++) //有n个点,所以要找n次
	{
		for(j=1; j<=n; j++)    
		{
			if(flag[j]==0)  //循环寻找度为0的点
			{
				flag[j]--;
				val[k++]=j;
				for(int x=1; x<=n; x++) //删除指向该点的边
					if(map[j][x])
						flag[x]--;  //使其度为0
				break;
			}
			if(j>n)
				return ;
		}
	}
}
int main()
{
	int i,j;
	while(cin>>n>>m)
	{
		memset(map,0,sizeof(map));
		memset(flag,0,sizeof(flag));    //初始化所有的点的度为0
		int a,b;
		for(i=1;i<=m;i++)
		{
			cin>>a>>b;
			if(!map[a][b])
			{
				map[a][b]=1;
				flag[b]++;  //度增加
			}
		}
		topsort();
		for(i=1;i<=n; i++)
			if(i!=n)
				cout<<val[i]<<" ";
			else
				cout<<val[i]<<endl;
	}
	return 0;
}


优先队列优化后的代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N=510+10;
vector<int> g[N];   //邻接表
int du[N],val[N];   
int n,m;
void  topsort()
{
    int i;
    priority_queue<int, vector<int>, greater<int> > q;//定义一个优先队列,并定义编号小的优先出队
    for(i=1;i<=n;i++)
        if(!du[i])
            q.push(i);
    int cnt=1;
    while(!q.empty())
    {
        int u=q.top();
        q.pop();
        val[cnt++]=u;
        for(i=0;i<g[u].size();i++)
        {
            int v=g[u][i];
            du[v]--;
            if(!du[v])
                q.push(v);
        }
    }
}
int main()
{
    int i,j,u,v;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        memset(du,0,sizeof(du));
        for(i=1;i<=n;i++)g[i].clear();
        for(i=1;i<=m;i++)
        {
            scanf("%d %d",&u,&v);
            g[u].push_back(v);
            du[v]++;
        }
        topsort();
        for(i=1;i<=n;i++)
        {
            if(i!=n)
                printf("%d ",val[i]);
            else
                printf("%d\n",val[i]);
        }
    }
    return 0;
}


HDU 1285 确定比赛名次(拓扑排序模板),布布扣,bubuko.com

HDU 1285 确定比赛名次(拓扑排序模板)

标签:style   color   os   io   strong   for   ar   代码   

原文地址:http://blog.csdn.net/u012313382/article/details/38395339

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!