hdu 2647 Reward(拓扑排序+反图)

题目链接:https://vjudge.net/contest/218427#problem/C

题目大意:

老板要给很多员工发奖金, 但是部分员工有个虚伪心态, 认为自己的奖金必须比某些人高才心理平衡; 但是老板很人道, 想满足所有人的要求, 并且很吝啬,想画的钱最少

输入若干个关系

a b

a c

c b

意味着a 的工资必须比b的工资高 同时a 的工资比c高; c的工资比b高

当出现环的时候输出-1

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
#define MAX 10005
int n, sum, ans;
int into[MAX], head[MAX], money[MAX];
struct Reward
{
    int to;
    int next;
} edge[2 * MAX];
void topu()
{
    int i, j, l, v;
    queue<int>Q;
    for (i = 1; i <= n; i++)
        if (into[i] == 0)
            Q.push(i);//把入度为0的点压如队列
    while (!Q.empty())
    {
        v = Q.front();//调用首位元素
        sum += money[v];
        Q.pop();//出队
        ans++; //用一个变量记录调用元素的总量,最后与n作比较
        for (l = head[v]; l != -1; l = edge[l].next)//与队首元素v有关的都枚举一遍
        {
            if (--into[edge[l].to] == 0)//如果入度-1为0,即为v的下一个元素
            {
                Q.push(edge[l].to);//将其压入队列
                money[edge[l].to] = money[v] + 1;//保证后一个要比前一个多1
            }
        }

    }
}
int main()
{
    int m, a, b, tot;
    while (scanf("%d%d", &n, &m) != EOF)
    {

        memset(head, -1, sizeof(head));
        memset(into, 0, sizeof(into));
        for (int i = 1; i <= n; i++)
            money[i] = 888;//所有人一开始都为888
        tot = 0;
        sum = 0;
        ans = 0;
        while (m--)
        {
            scanf("%d%d", &a, &b);//注意要逆过来,因为后一个b是基础的888,应当作为出度
            edge[tot].to = a;
            edge[tot].next = head[b];
            head[b] = tot++;
            into[a]++;//记录入度
        }
        topu();
        if (ans != n)//有可能在中间出现矛盾,必须保证每个地方都不矛盾
            sum = -1;
        cout << sum << endl;

    }
}

2018-04-10

原文地址:https://www.cnblogs.com/00isok/p/8783239.html

时间: 2024-11-11 20:30:22

hdu 2647 Reward(拓扑排序+反图)的相关文章

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

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 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 2647 Reward 拓扑排序

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 about how

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

HDU 2647 Reward(图论-拓扑排序)

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 ,a

HDU 4917 Permutation 拓扑排序的计数

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

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

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