HDU 2647 Reward【拓扑排序】

题意: 老板要给一些人发工资,但是一些人要求自己的工资必须比另一些人高,问最少需要发多少工资才能满足所有人的需求,如果不能满足输出-1,基础工资是 888.

分析: 由于 人数比较多 ,不能用邻接矩阵,排序用广搜排,如果排序结果发现有环(即找到的入度为 0 的点没有 n 个)的话,则无法满足所有人的要求。

         因为要使工资尽可能少,所以需要逆向拓扑排序。

#include<cstdio>
#include<cstring>
#define max(a,b)(a)>(b)?(a):(b)
#define clr(x)memset(x,0,sizeof(x))
struct node
{
    int to;
    int next;
}e[200003];
int tot;
int head[10003];
void add(int s,int u)
{
    e[tot].to=u;
    e[tot].next=head[s];
    head[s]=tot++;
}
int indegree[10005];
int q[100005];
int res[100005];
int main()
{
    int  ans,tmp,n,m,i,j,a,b,num,front,rear,x,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {            
        tot=1;
        clr(indegree);
        clr(head);
        clr(res);
        while(m--)
        {
            scanf("%d%d",&a,&b);
            add(b,a);
            indegree[a]++;
        }
        num=0;
        tmp=888;
        front=rear=0;
        for(i=1;i<=n;i++)
            if(indegree[i]==0)
                q[rear++]=i;
        while(front<rear)
        {
            x=q[front++];
            num++;
            for(j=head[x];j;j=e[j].next)
            {
                k=e[j].to;
                res[k]=max(res[x]+1,res[k]);
                indegree[k]--;
                if(indegree[k]==0)
                    q[rear++]=k;
            }
        }
        if(num!=n) 
            printf("-1\n");
        else {
            ans=0;
            for(i=1;i<=n;i++)
                ans+=res[i];
            printf("%d\n",888*n+ans);
        }
    }
    return 0;
}

 

posted @ 2012-07-28 15:13  'wind  阅读(207)  评论(0编辑  收藏  举报