HDU 2647Reward(拓扑排序)

来源:互联网 发布:换手率软件怎么样 编辑:程序博客网 时间:2024/04/16 14:17

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2647

去了趟厕所回来立马来灵感了啊。。第一次的时候纠结拓扑的顺序,加钱的时候顺序正好反着,在厕所的时候突然想到可以在加边的时候就倒着加,这样不就正好了吗。。于是回来怒敲代码,然后1Y,爽啊。。于是就多写点注释吧。。

#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <algorithm>using namespace std;int d[11000], head[11000], n, cnt, a[11000];struct node{    int u, v, w;    int next;}edge[22000];void add(int u, int v, int w){    edge[cnt].v=v;    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;}void tops(){    int i, j, x, ss=888, ans=0, s=0, flag=0;//ss表示当前层数要加的钱数;ans表示总钱数;s表示当前选的总人数    while(1)    {        x=0;        for(j=1;j<=n;j++)        {            if(d[j]==0)            {                a[x++]=j;//记录此层选的人                d[j]--;                s++;            }        }        ans+=x*ss;        if(x==0&&s<n)        {            flag=1;//说明出现环,则不能满足要求            break;        }        if(x==0)            break;        for(i=0;i<x;i++)//将与该层所有人相连的均降度        {            for(j=head[a[i]];j!=-1;j=edge[j].next)            {                if(edge[j].w==1)                {                    edge[j].w--;                    d[edge[j].v]--;                }            }        }        ss++;//层数递增    }    if(flag)        printf("-1\n");    else        printf("%d\n",ans);}int main(){    int m, a, b;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(d,0,sizeof(d));        memset(head,-1,sizeof(head));        cnt=0;        while(m--)        {            scanf("%d%d",&a,&b);            add(b,a,1);            d[a]++;        }        tops();    }    return 0;}



0 0
原创粉丝点击