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

Posted is_ok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于hdu 2647 Reward(拓扑排序+反图)的主要内容,如果未能解决你的问题,请参考以下文章

题解报告:hdu 2647 Reward(拓扑排序)

hdu 2647 Reward - 拓扑排序

HDU2647Reward(拓扑排序)

HDOJ 2647 Reward 逆拓扑排序+分层

Reward HDU - 2647

HDU 2647 Reward