Reward(hdu2647逆拓扑排序)

来源:互联网 发布:剑三霸气御姐捏脸数据 编辑:程序博客网 时间:2024/04/20 13:59

题意:工人发工资,每个个人都有要求,比某人多,问满足搜有人要求的最小总工资数。

思路:逆拓扑排序

之前都是谁大谁是头节点,但是这题如果谁大谁为头的话,那么头结点的工资将不停的改变,有点麻烦,但是根节点工资永远不会变,所以可以反过来,谁小谁当根节点,也就是出度变入度,入度变出度,剩下和拓扑一样,只不过在求个和

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<vector>using namespace std;int num[10005];int reward[10005];vector<int> v[10005];int c_sum = 0;bool find(int a,int b){    int i;    for(i = 0; i < v[b].size(); i++)    {        if(v[b][i] == a)            return true;    }    return false;}void topsort(int n){    queue<int> q;    int i,sum = 0;    for(i = 1; i <= n; i++)    {        if(!num[i])            q.push(i);    }    while(!q.empty())    {        int t = q.front();c_sum--;q.pop();sum += reward[t];        for(i = 0; i < v[t].size(); i++)        {            num[v[t][i]]--;            reward[v[t][i]] = reward[t]+1;            if(!num[v[t][i]])            {                q.push(v[t][i]);            }        }    }    if(c_sum > 0 )        printf("-1\n");    else        printf("%d\n",sum);}int main(){    int n,m;    while(scanf("%d%d",&n,&m) != EOF)    {        int i,a,b;        c_sum = n;        for(i = 1;i <= n; i++)        {            v[i].clear();            reward[i] = 888;            num[i] = 0;        }        for(i = 0; i < m; i++)        {            scanf("%d%d",&a,&b);            if(!find(a,b))            {                v[b].push_back(a);                num[a]++;            }        }        topsort(n);    }    return 0;}


原创粉丝点击