HDU 2647 Reward

来源:互联网 发布:淘宝购物车是什么意思 编辑:程序博客网 时间:2024/06/04 18:21

题意:发奖金,最低是888,有n个人,m条边(u,v)。u的奖金必须大于v。问最少发多少奖金。

解:我们建反向边(V,U),即(V比U的奖金少),记录入度。从入度为0的点开始top排序就行了。按照bfs的写法,每次top到下一层,只需要在这层的基础上奖金+1就行了。输出-1的情况,显然是中间出现了环,我们只需要记录,度能为0的个数。为n就输出解,否则为-1.

#include <iostream>#include <stdio.h>#include <math.h>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <string>#include <string.h>#include <map>#include <set>using namespace std;#define MAXN 10005#define LL long longint du[MAXN],vis[MAXN],ans[MAXN];int maze[MAXN][MAXN];vector<int>g[MAXN];struct node{    int num,id;    node(int num,int id):num(num),id(id){}};int main(){    int n,m,i,ans=0,tot;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(i=0;i<=n;i++)        {            g[i].clear();            du[i]=0;            vis[i]=0;        }        for(i=1;i<=m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            g[v].push_back(u);            du[u]++;        }        queue<node>q;        ans=0;        tot=0;        for(i=1;i<=n;i++)        {            if(du[i]==0)            {                vis[i]=1;                q.push(node(888,i));            }        }        while(!q.empty())        {            node tx=q.front();            ans+=tx.num;            q.pop();            tot++;            int sz=g[tx.id].size();            for(i=0;i<sz;i++)            {                du[g[tx.id][i]]--;                if(!vis[g[tx.id][i]])                {                    if(du[g[tx.id][i]]==0)                    {                        vis[g[tx.id][i]]=1;                        q.push(node(tx.num+1,g[tx.id][i]));                    }                }            }        }        if(tot==n)printf("%d\n",ans);        else printf("-1\n");    }    return 0;}


0 0