hdu2647 Reward

来源:互联网 发布:南望王师又一年 知乎 编辑:程序博客网 时间:2024/06/06 05:30

题目链接:点击打开链接

题意描述:在一个公司中,老板打算给员工发奖励,每个员工至少发888,但是员工之间奖励需要满足一些条件,如 a b代表a的奖励要比b至少多1,现在给定n个员工,和m的条件,问老板能否满足员工的要求(可能存在a比b多,同时b又比a多,此时无法满足),如果能够满足,老板至少需要准备多少?


解题思路:

1、我们可以根据条件建图,如果a比b多,则建一条b->a的有向边

2、判断有向图中是否存在回路,如果存在回路则无法满足要求(注意:图不保证是联通的,可能存在好多个联通块)

3、如果满足要求,我们可以把入度为0的点加入队列中,然后更新其他点

代码:

#pragma comment(linker,"/STACK:1024000000,1024000000")#include <cstdio>#include <cstring>#include <queue>#define MAXN 10010#define MAXE 20010#define INF 0x7fffffffusing namespace std;int head[MAXN];struct Edge{    int to,_next;}edge[MAXE*2];int tol;void init(){    tol=0; memset(head,-1,sizeof(head));}void addEdge(int from,int to){    edge[tol].to=to;edge[tol]._next=head[from];head[from]=tol++;}int n,m;int inn[MAXN],dis[MAXN];bool vis[MAXN];bool dfs(int s){    for(int i=head[s];i!=-1;i=edge[i]._next){        int to=edge[i].to;        if(vis[to]) return true;        else{            vis[to]=true;            if(dfs(to)) return true;            vis[to]=false;        }    }    return false;}int main(){    while(scanf("%d%d",&n,&m)!=EOF){        if(n==0) {printf("0\n");continue;}        init();        memset(inn,0,sizeof(inn));        int from,to;        bool flag=false;        for(int i=1;i<=m;++i){            scanf("%d%d",&to,&from);            if(from==to) flag=true;            addEdge(from,to);            inn[to]++;        }        if(flag) {printf("-1\n");continue;}        for(int i=1;i<=n;++i) dis[i]=0;        queue<int> q; while(!q.empty()) q.pop();        int i;        //flag=false;        for(i=1;i<=n;++i){           // if(inn[i]) continue;///注意,忽悠了连个联通块的情况,如一个孤立点和一个环的情况             //else flag=true;                        memset(vis,false,sizeof(vis));            vis[i]=true;            if(dfs(i)) break;            dis[i]=0;            q.push(i);        }        if(i<=n){ printf("-1\n");continue; }        while(!q.empty()){            int t=q.front(); q.pop();            for(int i=head[t];i!=-1;i=edge[i]._next){                int to=edge[i].to;                if(dis[to]<dis[t]+1){                    dis[to]=dis[t]+1;                    q.push(to);                }            }        }        int ans=0;        for(int i=1;i<=n;++i)            ans+=dis[i];        printf("%d\n",ans+n*888);    }    return 0;}

0 0
原创粉丝点击