hdu2647 Reward 拓扑排序
此题的关键在于分层次,最低一层的人的奖金是888,第二层是888+1 ……
分层可以这样实现。建立反向图。在拓扑排序的时候,第一批入度为0的点就处于第一层,第二批处于第二层 ……
由于是逐个遍历入度为0的点,所以怎么实现上面所说的第一批,第二批就需要动点脑。
可以试试下面的测试数据:
4 3
1 3
2 3
4 3
4 3
1 2
2 3
4 3
4 2
1 2
3 4
6 3
1 2
3 4
5 6
测试结果依次是: 3555 3556 3554 5331
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N = 10100, M =20010; 7 struct node 8 { 9 int to, next; 10 }; 11 node edge[M]; 12 int ind[N], head[N],que[N],ans[N]; 13 int iq,tot,t; 14 void topo(int n) 15 { 16 int i,k,j=0,x,y; 17 t=-1;x=0; 18 for(i=1;i<=n;i++) 19 if(ind[i]==0) que[j++]=i; 20 ans[++t]=j-x; 21 y=0; 22 x=j; 23 for(i=0;i<j;i++) 24 { 25 if(i==ans[t]+y) 26 { 27 ans[++t]=j-x; 28 x=j; 29 y=i; 30 } 31 32 int u=que[i]; 33 for(k=head[u]; k!=-1; k=edge[k].next) 34 { 35 ind[edge[k].to]--; 36 if(ind[edge[k].to]==0) 37 que[j++]=edge[k].to; 38 } 39 } 40 iq=j; 41 } 42 void addedge(int i,int j) 43 { 44 edge[tot].to=j;edge[tot].next=head[i];head[i]=tot++; 45 } 46 void init() 47 { 48 tot=0; 49 memset(ind,0,sizeof(ind)); 50 memset(head,-1,sizeof(head)); 51 } 52 int main() 53 { 54 //freopen("test.txt","r",stdin); 55 int n,m,i,j,k; 56 while(scanf("%d%d",&n,&m)!=EOF) 57 { 58 init(); 59 int flag=0; 60 while(m--) 61 { 62 scanf("%d%d",&i,&j); 63 if(i==j) flag=1; 64 if(flag) continue; 65 ind[i]++; 66 addedge(j,i); 67 } 68 topo(n); 69 if(iq<n||flag) printf("-1\n"); 70 else 71 { 72 int s=0; 73 for(i=0;i<=t;i++) s+=ans[i]*(i+888); 74 printf("%d\n",s); 75 } 76 } 77 return 0; 78 }