美文网首页
hdoj4857 逃生

hdoj4857 逃生

作者: 科学旅行者 | 来源:发表于2016-08-02 10:31 被阅读38次

    题目:

    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

    因为是给出先后顺序的排序,因此本题可以用拓扑排序。
    但此题有个奇怪的地方:如果两个人没有约束的先后关系,那么富的人排在前面(小号在前)。如果还是正向建图,此题就会出现错误答案。

    本题用的是逆向建图,然后拓扑排序。

    参考代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #define MAXV 30000+10
    #define MAXE 100000+10
    using namespace std;
    struct edge {
        int next,to;//利用链式前向星建立边;
    } e[MAXE];
    int head[MAXV],tot;
    void init() {
        memset(head,-1,sizeof(head));
        memset(e,0,sizeof(e));
        tot = 0;
    }
    void add_edge(int a,int b) {
        e[tot].next = head[a];
        e[tot].to = b;
        head[a] = tot++;    
    }
    int n,m,din[MAXV];
    vector<int> ans;//利用vector存放最终排序的结果;
    void topo_sort() {
        ans.clear();
        priority_queue<int> que;//优先队列(默认从大到小);//最后答案要反向输出;
        for (int i = 1;i <= n;++i) {
            if (din[i] == 0) {//每次存入度为0的点;
                que.push(i);
            }
        }
        while (!que.empty()) {
            int u = que.top();
            ans.push_back(u);
            que.pop();//去掉已加入结果的点;
            for (int i = head[u];i != -1;i = e[i].next) {
                int v = e[i].to;
                --din[v];
                if (din[v] == 0) {
                    que.push(v);
                }
            }
        }
        int count = 0;
        for (int i = ans.size()-1;i >= 0;--i) {
            if (count > 0) {
                printf(" ");
            }
            printf("%d", ans[i]);
            count++;
        }
        printf("\n");
    }
    int main() {
        int t;
        scanf("%d", &t);
        while (t--) {
            memset(din,0,sizeof(din));
            scanf("%d%d", &n, &m);
            int a,b;
            init();
            while (m--) {
                scanf("%d%d", &a, &b);
                add_edge(b,a);//反向建图;
                din[a]++;
            }
            topo_sort();
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:hdoj4857 逃生

          本文链接:https://www.haomeiwen.com/subject/nmyfsttx.html