hdu 2647 Reward(拓扑排序,反着来)

Reward

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 51   Accepted Submission(s) : 21

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

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 one may have demands of the distributing of rewards ,just like a‘s reward should more than b‘s.Dandelion‘s unclue wants to fulfill all the demands, of course ,he wants to use the least money.Every work‘s reward will be at least 888 , because it‘s a lucky number.

Input

One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000)
then m lines ,each line contains two integers a and b ,stands for a‘s reward should be more than b‘s.

Output

For every case ,print the least money dandelion ‘s uncle needs to distribute .If it‘s impossible to fulfill all the works‘ demands ,print -1.

Sample Input

2 1
1 2
2 2
1 2
2 1

Sample Output

1777
-1
#include <iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
int i,n,m;
int a[10002],cnt[10002];
vector<int> s[10002];
long long sum;
bool toposort()
{
    queue<int> Q;
    int num=0;
    for(int i=1;i<=n;i++)
        if (cnt[i]==0) {Q.push(i); a[i]=888;}
    while(!Q.empty())
    {
        int u=Q.front();
        num++;
        Q.pop();
        for(int i=0;i<s[u].size();i++)
        {
            cnt[s[u][i]]--;
            if (cnt[s[u][i]]==0)
                {
                    Q.push(s[u][i]);
                    a[s[u][i]]=max(a[u]+1,a[s[u][i]]);
                }
        }
    }
    if (num<n) return 0;
    return 1;
}
int main()
{

    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++) s[i].clear();
        memset(cnt,0,sizeof(cnt));
        for(i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&y,&x);
            s[x].push_back(y);
            cnt[y]++;
        }
        memset(a,0,sizeof(a));
        if (!toposort())
        {
            printf("-1\n");
            continue;
        }
        sum=0;
        for(i=1;i<=n;i++) sum+=a[i];
        printf("%lld\n",sum);
    }
    return 0;
}
时间: 2024-10-13 18:10:26

hdu 2647 Reward(拓扑排序,反着来)的相关文章

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> #

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)如果点