• HDU 1285 确定比赛名次 拓扑排序水题


    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
     
     
     
     
     
    我的拓扑排序是用队列写的,由于这里要求多种可能的时候,按照小到大的编号输出,
    所以改为优先队列priority_queue。
     
    优先队列默认大到小输出,所以要重载运算符<,使得从小到大
     
    优先队列取出元素不是 .front()  ,  而是  .top()  .
     
    拓扑排序的思路:
    1.用一个inde数组存储每个点的入度,邻接表保存边
    2.扫一遍,把入度为0的点加入queue
    3.每次从queue里面拿出一个元素,并删除这个元素,然后把这个元素通向的边v的入度-1、
     如果v的入度变为0,就把v也加入到queue里面。
    给点重新编号可以在点入队的时候,也可以在点出队的时候。
    因为每一个点都要编号,所以每个点都要进队一次
    设置一个计数器,每次出队时记录,若最后计数器>节点数,说明不是拓扑序。
     
     
     
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<queue>
     5 #include<vector>
     6 
     7 using namespace std;
     8 
     9 const int maxn=505;
    10 
    11 struct Node
    12 {
    13     int v;
    14     bool operator < (const Node &a) const
    15     {
    16         return a.v<v;
    17     }
    18 };
    19 
    20 vector<int>node[maxn];
    21 int f[maxn];
    22 int inde[maxn];
    23 
    24 int tot;
    25 
    26 void topo(int n)
    27 {
    28     tot=1;
    29 
    30     priority_queue<Node>que;
    31     while(!que.empty())
    32         que.pop();
    33 
    34     for(int i=1;i<=n;i++)
    35     {
    36         if(inde[i]==0)
    37         {
    38             Node temp;
    39             temp.v=i;
    40             que.push(temp);
    41         }
    42     }
    43 
    44     while(!que.empty())
    45     {
    46         Node u=que.top();
    47         que.pop();
    48         f[tot++]=u.v;
    49 
    50         for(int i=0;i!=node[u.v].size();i++)
    51         {
    52             int w=node[u.v][i];
    53             inde[w]--;
    54             if(inde[w]==0)
    55             {
    56                 Node temp;
    57                 temp.v=w;
    58                 que.push(temp);
    59             }
    60         }
    61     }
    62 }
    63 
    64 int main()
    65 {
    66     int n;
    67 
    68     while(scanf("%d",&n)!=EOF)
    69     {
    70         int m;
    71         scanf("%d",&m);
    72 
    73         memset(inde,0,sizeof(inde));
    74         for(int i=1;i<=n;i++)
    75             node[i].clear();
    76 
    77         int u,v;
    78 
    79         for(int i=1;i<=m;i++)
    80         {
    81             scanf("%d%d",&u,&v);
    82             node[u].push_back(v);
    83             inde[v]++;
    84         }
    85 
    86         topo(n);
    87 
    88         for(int i=1;i<tot-1;i++)
    89             printf("%d ",f[i]);
    90         printf("%d
    ",f[tot-1]);
    91     }
    92 
    93     return 0;
    94 }
    View Code
     
     
     
     
     
     
     
     
  • 相关阅读:
    stat函数讲解
    ptrace 人人小站
    调试器工作原理——基础篇
    open和fopen的区别:
    memset ,memcpy 和strcpy 的根本区别?
    log4j日志配置详解
    jvm调优的参数设置
    mysql的密码设置
    java基础类、接口、成员属性的修饰符
    java基础之类(包含内部类)与接口的特点
  • 原文地址:https://www.cnblogs.com/-maybe/p/4491896.html
Copyright © 2020-2023  润新知