题目大意:有一种关系a,b代表a的奖金比b的高,最少的奖金为888,求总共需要的最少的
钱数,让所有满足关系的人都得到应有的奖金,否则输出-1;
思路:反向进行拓扑,主要是统计奖金。
注意可能给定的数据是深林,所以可以先统计出度为0的点赋值为888,然后边拓扑边统计。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #define ll __int64 using namespace std; int head[20010],cnt,du[20010],p[20010]; struct node { int to,next; }q[20010]; int n,reward[20010]; void topo() { int i,j,k; queue<int>qu; for(i=1;i<=n;i++) { if(du[i]==0) { reward[i]=888; qu.push(i); } } int t,sum=0; while(!qu.empty()) { t=qu.front(); qu.pop(); sum++; for(k=head[t];k!=-1;k=q[k].next) { du[ q[k].to ]--; if(!du[ q[k].to ]) { reward[q[k].to ]=reward[t]+1; qu.push(q[k].to ); } } } if(sum!=n) { printf("-1\n");return ; } ll ans=0; for(i=1;i<=n;i++) { ans+=reward[i]; } printf("%lld\n",ans); } int main() { int m,i,j,k; while(~scanf("%d%d",&n,&m)) { int a,b; cnt=1; memset(head,-1,sizeof(head)); memset(du,0,sizeof(du)); for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); q[i].to=a; q[i].next=head[b]; head[b]=cnt++; du[a]++; } topo(); } return 0; }