hdu 2647 Reward (拓扑排序)
来源:互联网 发布:java语言程序设计进阶 编辑:程序博客网 时间:2024/04/19 09:16
/*比较明显的拓扑排序。具体看注释*/#include<iostream>#include<cstdio>#include<cstring>#include<vector>#define N 10001using namespace std;int n,m,x,y,tsum,indx,flag;struct Node{ int in;//入度 int sum;//该点获得的奖金 int next;//后续节点数 vector<int> work;//储存后续节点下标}worker[N];void init(){ for(int i=1;i<=n;i++) { worker[i].sum=888; worker[i].in=0; worker[i].next=0; worker[i].work.clear(); } tsum=0;}bool topsort(){ while(true) { flag=0; for(int j=1;j<=n;j++) { if(worker[j].in>0) { flag=1; } else if(worker[j].in==0) { worker[j].in--; tsum+=worker[j].sum;//当该点入度为0时,该点的奖金就是最小能得到的合理奖励 for(int k=0;k<worker[j].next;k++)//更新该点的后续节点 { indx=worker[j].work.at(k); worker[indx].in--; if(worker[indx].sum<worker[j].sum+1) worker[indx].sum=worker[j].sum+1; } break;//不要忘记了。。因为每更新点后 。都要从头来一遍 } if(j==n) { if(flag) return false; else return true; } } }}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { init(); while(m--) { scanf("%d%d",&x,&y); worker[y].next++; worker[y].work.push_back(x); worker[x].in++; } if(topsort()) { printf("%d\n",tsum); } else printf("-1\n"); }}