您的位置:首页 > 其它

HDU 1285 确定比赛名次(简单拓扑排序)

2014-06-14 11:58 274 查看
HDU 1285 确定比赛名次(简单拓扑排序)
http://acm.hdu.edu.cn/showproblem.php?pid=1285
题意:

给你N个点M条有向边,要求你输出字典序最小的拓扑排序序列.

分析:

前面已经做过很多这种题了,没什么说的直接输出字典序最小的拓扑序列即可.

注意:非递归求字典序最小的拓扑序列需要用到优先队列,且要是小值优先的队列.大致的思想就是队列Q总是将当前在入度为0的最小节点优先取出.保证了字典序最小.

AC代码:

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=500+10;
int n,m;
vector<int> G[maxn];
int in[maxn];
void topo()
{
    priority_queue<int,vector<int>,greater<int> > Q; //保证小值int先出队列
    int ans[maxn],cnt=0;
    for(int i=1;i<=n;i++)if(in[i]==0) Q.push(i);
    while(!Q.empty())
    {
        int u=Q.top(); Q.pop();
        ans[cnt++]=u;
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(--in[v]==0)
                Q.push(v);
        }
    }
    printf("%d",ans[0]);
    for(int i=1;i<n;i++)
        printf(" %d",ans[i]);
    puts("");
}
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(in,0,sizeof(in));
        for(int i=1;i<=n;i++) G[i].clear();
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            in[v]++;
        }
        topo();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: