HDU 2647 Reward

来源:互联网 发布:js下拉框默认选中 编辑:程序博客网 时间:2024/05/16 08:16

题目大意:一个公司在春节的时候要给员工发奖金,每个人的奖金初始值都为888,但是在发奖金的时候这里有一些要求,就是(a,b),代表a的工资必须比b的工资高,给你n个人和m个关系,现在让你求最少需要发多少奖金,如果根据这个关系可以求出最少奖金数,输出最少的奖金,否则的话输出-1。

思路:经过分析之后会发现这是一个拓扑排序的题目,为什么会这样说那,可以这样看,这里存在个链式关系,可以同时这个链还是有方向的,同时如果满足所有的m个要求的话,肯定是不存在环的,此时我们就可以根据拓扑排序来做这个题,同时要求发放的奖金最少,那么我们就让a的奖金比b的奖金高一就好了。

一开始错了两遍,是因为定义了全局变量,多组输入忘记初始化。。。。

代码如下:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <vector>using namespace std;const int MAXN=1e4+10;int ans[MAXN];int deg[MAXN];int vis[MAXN];vector<int> v[MAXN];struct Per{    int idx;    int d;    Per() {}    Per(int a,int b)    {        idx=a,d=b;    }    bool operator<(Per p1)const    {        return d>p1.d;    }} per[MAXN];int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        for(int i=0; i<=n; i++) v[i].clear();        memset(deg,0,sizeof(deg));        memset(vis,0,sizeof(vis));        memset(ans,0,sizeof(ans));        for(int i=0; i<m; i++)        {            int x,y;            scanf("%d%d",&x,&y);            deg[x]++;            v[y].push_back(x);        }        queue<int> p;        for(int i=1; i<=n; i++)        {            per[i].idx=i;            per[i].d=deg[i];            if(deg[i]==0) p.push(i);        }        int cnt=0;        while(!p.empty())        {            cnt++;            int x=p.front();            ans[x]=max(ans[x],888);            p.pop();            vis[x]=1;            for(int i=0; i<v[x].size(); i++)            {                int son=v[x][i];                if(vis[son]) continue;                ans[son]=max(ans[son],ans[x]+1);                deg[son]--;                if(deg[son]==0) p.push(son);            }        }        if(cnt==n)        {            long long sum=0;            for(int i=1; i<=n; i++)                sum+=(1ll)*ans[i];            printf("%lld\n",sum);        }        else printf("-1\n");    }    return 0;}


原创粉丝点击