HDU 2647 -- Reward (拓扑排序)

来源:互联网 发布:3d仿真软件 编辑:程序博客网 时间:2024/04/19 11:23

题目大意:老板给员工发奖金,每个员工对自己的奖金都有要求。他们的要求类似这样:A的奖金必须多余B。每个员工基础奖金888元。问:是否能满足所有员工?如果满足所有员工的要求,所发的总奖金最少是多少。

思路分析:对于输入的关系(a,b)要注意是a的奖金大于b,因为要求最少的金额,同时我们也能不确定最长的关系(也就是奖金最高为多少)所以我们倒过来建立关系,即(b,a),最少的钱数为888,以此依次增加。

代码实现:

#include<cstdio>#include<cstring>#include<queue>using namespace std;int top,sum;int degree[10010],money[10010];queue<int>q;struct Edge{    int v;    Edge *next;}*head[20010],e[20010];void Addedge(int from,int to){    Edge *p=&e[top++];    p->v=to;    p->next=head[from];    head[from]=p;}void TupSort(int n){    for(int i=1;i<=n;i++){        if(degree[i]==0)            q.push(i);    }    while(!q.empty()){        int a=q.front();        q.pop();//a删除入度为0的结点        for(Edge *p=head[a];p;p=p->next){ 让以a为头结点的所有入度减1            degree[p->v]--;            if(degree[p->v]==0){//入度为0,加入队列,同时此点的钱比它的头结点的钱增1                money[p->v]=money[a]+1;                q.push(p->v);            }        }    }    for(int i=1;i<=n;i++){        if(degree[i]!=0){            printf("-1\n");            return;        }    }    for(int i=1;i<=n;i++){        sum+=money[i];    }    printf("%d\n",sum);}int main(){    int n,m;    while(~scanf("%d%d",&n,&m)){        memset(head,0,sizeof(head));        memset(degree,0,sizeof(degree));        top=0,sum=0;        for(int i=1;i<=n;i++)            money[i]=888;        for(int i=0;i<m;i++){            int a,b;            scanf("%d%d",&a,&b);            Addedge(b,a);            degree[a]++;        }        TupSort(n);    }    return 0;}


0 0
原创粉丝点击