HDU-1285 简单拓扑排序

确定比赛名次

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 35253    Accepted Submission(s): 13787

Problem Description

有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。

Input

输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。

Output

给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。

其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。

Sample Input

4 3
1 2
2 3
4 3

Sample Output

1 2 4 3

拓扑排序是对有向无环图来说的,无向图和有环的有向图是没有拓扑排序的。对一个有向无环图G进行拓扑排序是将G中的所有点排成一个线性序列,使得图中任意一个有向无环图中任意一个顶点u和v若图中存在边<u,v>,则u在线性序列中出现在v之前。对有向图进行拓扑排序产生的线性序列称为满足拓扑排序次序的序列,简称拓扑排序。一个有向无环图通常可以 表示某种动作序列或方案,而有向无环图的拓扑序列通常表示为某种方案切实可行。

找入度为零的点,入栈,删去其关联的边。再次重复操作,直到所有点全被查找

#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define each(i,n) (int i=1;i<=(n);++i)
using namespace std;
int head[100004],rudu[100004];
struct node
{
    int to,next;
}bian[100004];
int top=0;
int queu[100004];
void add(int a,int b)
{
    bian[top].to=b;
    bian[top].next=head[a];
    head[a]=top++;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int a,b;
        memset(head,-1,sizeof(head));
        memset(rudu,0,sizeof(rudu));
        for(int i=0;i<m;i++)
        {
            cin>>a>>b;
            add(a,b);
            rudu[b]++;
        }
        int c=0;
        while(c<n)
        {
            for(int i=1;i<=n;i++)
            {
                if(rudu[i]==0)
                {
                    queu[c++]=i;
                    rudu[i]=-1;
                    for(int j=head[i];j!=-1;j=bian[j].next)
                        rudu[bian[j].to]--;
                    break;
                }
            }
        }
        for(int i=0;i<c;i++)
        {
            printf(i==c-1?"%d\n":"%d ",queu[i]);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/SparkPhoneix/p/9378362.html

时间: 2024-11-08 19:45:47

HDU-1285 简单拓扑排序的相关文章

hdu 2647 Reward (拓扑排序分层)

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3815    Accepted Submission(s): 1162 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wa

HDU 4917 Permutation 拓扑排序的计数

题意: 一个有n个数的排列,给你一些位置上数字的大小关系.求合法的排列有多少种. 思路: 数字的大小关系可以看做是一条有向边,这样以每个位置当点,就可以把整个排列当做一张有向图.而且题目保证有解,所以只一张有向无环图.这样子,我们就可以把排列计数的问题转化为一个图的拓扑排序计数问题. 拓扑排序的做法可以参见ZJU1346 . 因为题目中点的数量比较多,所以无法直接用状压DP. 但是题目中的边数较少,所以不是联通的,而一个连通块的点不超过21个,而且不同连通块之间可以看做相互独立的.所以我们可以对

hdu 4857 逃生 拓扑排序+优先队列,逆向处理

hdu4857 逃生 题目是求拓扑排序,但不是按照字典序最小输出,而是要使较小的数排在最前面. 一开始的错误思路:给每个点确定一个优先级(该点所能到达的最小的点),然后用拓扑排序+优先对列正向处理,正向输出.这是错误的,如下样例: 1 5 4 5 2 4 3 2 1 3 1 正确的解法:是反向建边,点大的优先级高,用拓扑排序+优先队列,逆向输出序列即可. 根据每对限制,可确定拓扑序列,但此时的拓扑序列可能有多个(没有之间关系的点的顺序不定).本题要求较小的点排到前面,则可确定序列. (1)如果点

ACM: hdu 2647 Reward -拓扑排序

hdu 2647 Reward Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble

hdu 5438 Ponds 拓扑排序

Ponds Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1001&cid=621 Description Betty owns a lot of ponds, some of them are connected with other ponds by pipes, and there will not be more than one

hdu1285简单拓扑排序

1 //hdu 1285 2 3 #include<stdio.h> 4 #include<string.h> 5 #include<stack> 6 using namespace std; 7 int map[600][600],n,count[600],seq[600],ff; 8 int topo() 9 { 10 int i,j; 11 ff=0; 12 while(ff<n)//当为排完 13 { 14 for(i=1;i<=n;i++)//从小

HDU 2647 Reward(拓扑排序)

Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards. The workers will compare their rewards ,and some

hdu 2647 Reward 拓扑排序。

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4599    Accepted Submission(s): 1400 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he w

hdu 4857 逃生 拓扑排序+PQ,剥层分析

pid=4857">hdu4857 逃生 题目是求拓扑排序,但不是依照字典序最小输出,而是要使较小的数排在最前面. 一開始的错误思路:给每一个点确定一个优先级(该点所能到达的最小的点).然后用拓扑排序+优先对列正向处理,正向输出.这是错误的.例如以下例子: 1 5 4 5 2 4 3 2 1 3 1 正确的解法:是反向建边.点大的优先级高,用拓扑排序+优先队列,逆向输出序列就可以. 依据每对限制,可确定拓扑序列,但此时的拓扑序列可能有多个(没有之间关系的点的顺序不定).本题要求较小的点排到

HDU 2647 逆向拓扑排序

令每一个员工都有一个自己的等级level[i] , 员工等级越高,那么工资越高,为了使发的钱尽可能少,所以每一级只增加一单位的钱 输入a b表示a等级高于b,那么我们反向添加边,令b—>a那么in[a]++,再进行拓扑排序,每次都让边的终点的level值大于起始点,那么要用max取较大值 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5