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; }