HDU 2647 Reward (拓扑排序)

来源:互联网 发布:php 下载pdf文件 编辑:程序博客网 时间:2024/05/17 15:57

点击打开链接

Reward

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7885    Accepted Submission(s): 2511


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 11 22 21 22 1
 


Sample Output
1777-1
 


Author
dandelion
 


Source
曾是惊鸿照影来
 


Recommend
yifenfei   |   We have carefully selected several similar problems for you:  3342 1811 2680 2112 2094 

老板要给员工发奖金,每个工人的奖金最少是888元,并且一名员工a要求比另一名员工b的工资高。为了满足所有员工的要求,求老板最少需要发多少奖金,如果不能满足要求则输出-1.

很容易就能想到这是一道拓扑排序题,判断图是否为有向无环图,如果有环就代表不能满足需求输出-1.

注意:输入a,b的时候有向边是b-->a.而不是a-->b.所以反向建图。
#include <bits/stdc++.h>using namespace std;const int maxn=1e5+10;int head[maxn];bool vis[maxn];int deg[maxn],reward[maxn];      //deg表示入度   reward表示奖金struct node{    int to;    int next;}edge[maxn];int cnt;int n,m;void init(){    cnt=0;    memset(head,-1,sizeof(head));    memset(deg,0,sizeof(deg));}void Topsort()                //拓扑排序{   queue<int>que;             //搞不懂为什么用优先队列就错了    for(int i=1;i<=n;i++)    {        if(!deg[i])        {            que.push(i);        //先筛选出入度为0的点        }    }    int num=0;    int ans=0;    while(!que.empty())    {        int q=que.front();        que.pop();        num++;        ans+=reward[q];        for(int i=head[q];i!=-1;i=edge[i].next)          {            node e=edge[i];            deg[e.to]--;     //删除以这个点弧尾的弧,并使弧头的入度-1            if(!deg[e.to])                               {                que.push(e.to);  //找到了下一层的一个点                reward[e.to]=reward[q]+1;  //更新奖金            }        }    }    if(num!=n)        printf("-1\n");    else        printf("%d\n",ans);}int main(){    int a,b;    while(~scanf("%d%d",&n,&m))    {        init();        for(int i=1;i<=m;i++)        {            scanf("%d%d",&a,&b);            deg[a]++;            edge[cnt].to=a;            edge[cnt].next=head[b];            head[b]=cnt++;        }        for(int i=1;i<=n;i++)            reward[i]=888;           //初始化奖金        Topsort();    }}


0 0