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
*/



posted @ 2011-07-17 10:47  沐阳  阅读(324)  评论(0编辑  收藏  举报