HDU 5638 拓扑排序+优先队列

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5638

题意:

给你一个DAG图,删除k条边,使得能个得到字典序尽可能小的拓扑排序

题解:

把拓扑排序的算法稍微改一下,如果某个顶点的入度小于k也把它加到优先队列里面去。

k减小后队列里面会有些点不满足<=k,直接踢出来就好了。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<functional>
using namespace std;

typedef long long LL;
const int maxn = 101010;
const int maxm = maxn << 1;
const int mod = 1e9 + 7;
int n, m, k;

vector<int> G[maxn];
int ind[maxn], used[maxn],inq[maxn];

void init() {
    for (int i = 1; i <= n; i++) G[i].clear();
    memset(ind, 0, sizeof(ind));
    memset(inq, 0, sizeof(inq));
    memset(used, 0, sizeof(used));
}

int main() {
    int tc;
    scanf("%d", &tc);
    while (tc--) {
        scanf("%d%d%d", &n, &m, &k);
        init();
        for (int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            ind[v]++;
        }
        priority_queue<int,vector<int>,greater<int> > pq;
        for (int i = 1; i <= n; i++) {
            if (ind[i] <= k) pq.push(i),inq[i] = 1;
        }
        vector<int> ans;
        while (!pq.empty()) {
            while (ind[pq.top()]>k) {
                inq[pq.top()] = 0;
                pq.pop();
            }
            int x = pq.top(); pq.pop();
            inq[x] = 0;
            k -= ind[x];
            ans.push_back(x); used[x] = 1;
            for (int i = 0; i < G[x].size(); i++) {
                int v = G[x][i];
                ind[v]--;
                if (ind[v] <= k&&!inq[v]&&!used[v]) {
                    pq.push(v);
                    inq[v] = 1;
                }
            }
        }
        LL cnt = 0;
        for (int i = 0; i < ans.size(); i++) {
            cnt += (LL)(i + 1)*ans[i];
            cnt %= mod;
        }
        printf("%lld\n", cnt);
    }
    return 0;
}
时间: 2024-10-14 00:58:57

HDU 5638 拓扑排序+优先队列的相关文章

HDU 4857 拓扑排序 优先队列

n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得到的序列就是从大到小的,最后倒序输出就行了. 写这题的时候头好痛阿肚子好痛阿,再也不想熬夜了,一点效率都没有. /** @Date : 2017-09-29 19:29:12 * @FileName: HDU 4857 拓扑排序 + 优先队列.cpp * @Platform: Windows * @

HDU 1285 确定比赛名次(拓扑排序+优先队列)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前.现在请你编程序确定排名. Input 输入有若干组,每组中的第一行为二个数N(1<=N<

HDU 4857 (反向拓扑排序 + 优先队列)

题意:有N个人,M个优先级a,b表示a优先于b,并且每个人有个编号的优先级,输出顺序. 思路来自:与PKU3687一样 在基本的拓扑排序的基础上又增加了一个要求:编号最小的节点要尽量排在前面:在满足上一个条件的基础上,编号第二小的节点要尽量排在前面:在满足前两个条件的基础上,编号第三小的节点要尽量排在前面--依此类推.(注意,这和字典序是两回事,不可以混淆.) 如图 1 所示,满足要求的拓扑序应该是:6 4 1 3 9 2 5 7 8 0. 图 1 一个拓扑排序的例子 一般来说,在一个有向无环图

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

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

hdu--1285 &amp;&amp; 4857 --正向 || 逆向拓扑排序 &amp;&amp; 优先队列

头太晕了 喝了太多 .. 就想提一点 对于 拓扑排序的这2题 为什么一个是正向 一个是逆向 主要是看题目要求  因为拓扑排序的结果总是有很多种存在的 一般来说 它会让你输出它指定要求的形式的答案 那么 如果是按字典序输出 就是 greater<int> 情况下的优先队列 并且 正向 如果是尽量使小的数字 靠前输出 而不是追求 字典序 可以考虑 逆向拓扑 逆向输出 但 这些都不是唯一的 一定要分析好题目 曾经 看过一个讲动态规划的word  说拓扑是为DP作准备的 似乎有点道理 这两题 代码 实

hdu4857 逃生 反拓扑排序+优先队列, 靠前的数字的优先输出.

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 734    Accepted Submission(s): 199 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. 同时,社会是

hdoj 4857 逃生(逆向拓扑排序+优先队列)

逃生 点击打开链接 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2161    Accepted Submission(s): 608 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前

hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 52 Problem Description A topological sort or topological ordering of a directed

hdu 4857 逃生 (拓扑排序+优先队列)

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 688    Accepted Submission(s): 190 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平