zoukankan      html  css  js  c++  java
  • BestCoder Round #1 1001 逃生 (HDU 4857)

    逃生

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 604    Accepted Submission(s): 159


    Problem Description
    糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

    现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。
    同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。

    负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。

    那么你就要安排大家的顺序。我们保证一定有解。
     
    Input
    第一行一个整数T(1 <= T <= 5),表示测试数据的个数。
    然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)和m(1 <= m <= 100000),分别表示人数和约束的个数。

    然后m行,每行两个整数a和b,表示有一个约束a号必须在b号之前。a和b必然不同。
     
    Output
    对每个测试数据,输出一行排队的顺序,用空格隔开。
     
    Sample Input
    1 5 10 3 5 1 4 2 5 1 2 3 4 1 4 2 3 1 5 3 5 1 2
     
    Sample Output
    1 2 3 4 5
     
    思路:拓扑排序。逆向建图。
     
    先贴vector + priority_queue 的代码。 跑了 296ms c++
     
     1 /*======================================================================
     2  *           Author :   kevin
     3  *         Filename :   逃生.cpp
     4  *       Creat time :   2014-07-20 19:03
     5  *      Description :
     6 ========================================================================*/
     7 #include <iostream>
     8 #include <algorithm>
     9 #include <cstdio>
    10 #include <cstring>
    11 #include <queue>
    12 #include <cmath>
    13 #define clr(a,b) memset(a,b,sizeof(a))
    14 #define M 30005
    15 using namespace std;
    16 int in[M],ans[M];
    17 vector<int>vec[M];
    18 void slove(int n)
    19 {
    20     priority_queue<int>que;
    21     for(int i = 1; i <= n; i++){
    22         if(in[i] == 0) {
    23             que.push(i);
    24         }
    25     }
    26     int cnt = n;
    27     while(!que.empty()){
    28         int t = que.top();
    29         ans[--cnt] = t;
    30         que.pop();
    31         int len = vec[t].size();
    32         for(int i = 0; i < len; i++){
    33             if(--in[vec[t][i]] == 0){
    34                 que.push(vec[t][i]);
    35             }
    36         }
    37     }
    38     int flag = 0;
    39     for(int i = 0; i < n; i++){
    40         if(!flag){
    41             printf("%d",ans[i]);
    42             flag = 1;
    43         }
    44         else{
    45             printf(" %d",ans[i]);
    46         }
    47     }
    48 }
    49 int main(int argc,char *argv[])
    50 {
    51     int t;
    52     scanf("%d",&t);
    53     while(t--){
    54         int n,m;
    55         scanf("%d%d",&n,&m);
    56         int a,b;
    57         clr(in,0);
    58         for(int i = 0; i < m; i++){
    59             scanf("%d%d",&a,&b);
    60             vec[b].push_back(a);
    61             in[a]++;
    62         }
    63         slove(n);
    64         printf("
    ");
    65         for(int i = 0; i < M; i++){
    66             vec[i].clear();
    67         }
    68     }
    69     return 0;
    70 }
    View Code

    然后是链式前向星 + priority_queue。 跑了203ms  c++  

     1 /*======================================================================
     2  *           Author :   kevin
     3  *         Filename :   逃生1.cpp
     4  *       Creat time :   2014-07-21 10:52
     5  *      Description :
     6 ========================================================================*/
     7 #include <iostream>
     8 #include <algorithm>
     9 #include <cstdio>
    10 #include <cstring>
    11 #include <queue>
    12 #include <cmath>
    13 #define clr(a,b) memset(a,b,sizeof(a))
    14 #define M 300005
    15 using namespace std;
    16 int head[M],ans[M],in[M];
    17 struct Node
    18 {
    19     int to,next;
    20 };
    21 Node node[M];
    22 void AddEdges(int i,int j,int k)
    23 {
    24     node[k].to = j;
    25     node[k].next = head[i];
    26     head[i] = k;
    27 }
    28 void slove(int n)
    29 {
    30     priority_queue<int>que;
    31     for(int i = 1; i <= n; i++){
    32         if(in[i] == 0)
    33             que.push(i);
    34     }
    35     int cnt = n,k;
    36     while(!que.empty()){
    37         int t = que.top();
    38         ans[--cnt] = t;
    39         que.pop();
    40         for(k = head[t]; k != -1; k = node[k].next){
    41             if(--in[node[k].to] == 0){
    42                 que.push(node[k].to);
    43             }
    44         }
    45     }
    46     int flag = 0;
    47     for(int i = 0; i < n; i++){
    48         if(!flag){
    49             printf("%d",ans[i]);
    50             flag = 1;
    51         }
    52         else{
    53             printf(" %d",ans[i]);
    54         }
    55     }
    56 }
    57 int main(int argc,char *argv[])
    58 {
    59     int t;
    60     scanf("%d",&t);
    61     while(t--){
    62         int n,m;
    63         scanf("%d%d",&n,&m);
    64         int a,b;
    65         clr(in,0);
    66         clr(head,-1);
    67         int cnt = 1;
    68         for(int i = 0; i < m; i++){
    69             scanf("%d%d",&a,&b);
    70             AddEdges(b,a,cnt++);
    71             in[a]++;
    72         }
    73         slove(n);
    74         printf("
    ");
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    【RQNOJ 5201】数字组合【DP】
    【POJ 2279】Mr. Young's Picture Permutations【DP】
    【POJ 2279】Mr. Young's Picture Permutations【DP】
    【POJ 2279】Mr. Young's Picture Permutations【DP】
    【CODEVS 2185】最长公共上升子序列【DP】
    【CODEVS 2185】最长公共上升子序列【DP】
    【CODEVS 2185】最长公共上升子序列【DP】
    【洛谷P1368】工艺【最小表示法】
    【洛谷P1368】工艺【最小表示法】
    【洛谷P1368】工艺【最小表示法】
  • 原文地址:https://www.cnblogs.com/ubuntu-kevin/p/3860665.html
Copyright © 2011-2022 走看看