HDU-2647 Reward 拓扑排序
这题的拓扑排序有一个一定要处理的地方就是要将一次所能够pop出来的点在一次循环中全部取出来,然后再在基本工资的基础上自增一。
代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct a { int sign; struct a *next; } E; struct b { int cnt; struct a *next; } V[10005]; int queue[10005], front, rear, M, N, hash[10005]; void insert( int x, int y ) // 要求边为从y指向x; { E *e= ( E * )malloc( sizeof( E ) ); e-> sign= x; e-> next= V[y]. next; V[y]. next= e; V[x]. cnt++; } void _free( int v ) { if( V[v]. next== NULL ) { return; } E *p= V[v]. next; while( p ) { V[p-> sign]. cnt--; E *q= p; p= p-> next; free( q ); } V[v]. next= NULL; } int main( ) { while( scanf( "%d %d", &N, &M )!= EOF ) { front= rear= 0; int cnt= 0; memset( hash, 0, sizeof( hash ) ); memset( V, 0, sizeof( V ) ); for( int i= 1; i<= M; ++i ) // 有M组关系 { int x, y; scanf( "%d %d", &x, &y ); insert( x, y ); } int sum= 0, base= 888, flag= 0; while( cnt< N ) { int sign= 0; for( int i= 1; i<= N; ++i ) { if( V[i]. cnt== 0&& !hash[i] ) { hash[i]= 1; sign= 1; queue[rear++]= i; } } if( !sign ) { flag= 1; break; } while( front!= rear ) { _free( queue[front++] ); cnt++; sum+= base; } base++; } printf( flag? "-1\n": "%d\n", sum ); } } /* 2 1 1 2 2 2 1 2 2 1 5 4 1 2 2 3 2 4 1 5 */