poj 3687(拓扑排序)

http://poj.org/problem?id=3687

题意:有一些球他们都有各自的重量,而且每个球的重量都不相同,现在,要给这些球贴标签。如果这些球没有限定条件说是哪个比哪个轻的话,那么默认的前面比后的要请,而且这n个球的重量也正好是分布在1-n这个范围内,现在要你求出他们各自所占的重量。

思路:最开始,我也是想到了用拓扑排序,但是它的入度值我确定不了,然后去看discuss,里面说对每个判断条件反向建图,然后在用最大优先队列。我不理解这是什么意思。然后看了下别人的博客,模拟了一下大概的过程。

比如说

4 1

4 1

那么答案是2 3 4 1

反向建图,那么也就是digree[ 4 ] ++;

然后,其他的数入度值都是为0,所以都进优先队列。

那么现在优先队列就是有 1 2 3 这三个数。

然后,location[ 3 ] = 4;

再去寻找有没有与3相比较过的数。

然后, location[ 2 ] = 3;

再去找有没有与2相比较过的数。

然后,location[ 1 ] = 2;

再去找有没有与1比较过的数,如果有的话,把那么数入队列,那么4就入了队列。

然后,location[ 4 ] = 1;

然后反向输出,这就是结果,而那么 4 3 2 1 这是怎么来的呢,首先用一个变量num等于n。

然后每使用一次,这个变量就--。上面的也就是相当于 location[ 3 ] = 4 --。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <queue>
 4 #define maxn 210
 5 
 6 using namespace std;
 7 
 8 int digree [ maxn ];        //这个就是入度值。
 9 int judge [ maxn ][ maxn ];     //这个是用来判断有没有重边的。
10 int location [ maxn ];
11 int m,n;
12 
13 priority_queue<int >s;     //这个是默认的最大优先队列。
14 
15 int topsort()
16 {
17     int num = n;
18     for( int i = 1 ; i <= n ; i++ )
19         if(!digree[ i ]) s.push( i );
20     if( s.empty() )  return 0;    //如果没有入度为0的,则说明构成了一个环。
21     while( !s.empty() )
22     {
23         int tmp =s.top();
24         s.pop();
25         location [ tmp ] = num--;
26         for( int i = 1 ; i <= n ; i++ )
27         {
28             if( judge[ i ][ tmp ] )
29             {
30                 judge[ i ][ tmp ] = 0;
31                 digree[ i ] --;
32                 if( !digree[ i ] ) s.push( i );
33             }
34         }
35     }
36     if( num != 0 ) return 0;    //如果这里Num 不能等于0,那么说明最少还有两个是无法确定的。
37     return 1;
38 }
39 
40 
41 int main()
42 {
43     int t,a,b;
44     scanf("%d",&t);
45     while( t -- )
46     {
47         memset( digree , 0 , sizeof( digree ) );
48         memset( judge , 0 , sizeof( judge ) );
49         memset( location , 0 , sizeof( location ) );
50         scanf("%d%d",&n,&m);
51         for( int i = 1 ; i <= m ; i ++ )
52         {
53             scanf("%d%d",&a,&b);
54             if(judge[ a ][ b ] > 0) continue;   //判重。
55             judge[ a ][ b ] = 1;
56             digree [ a ] ++;
57         }
58         a = topsort();
59         if( a ) {
60             int i = 1;
61             for( ; i < n ; printf("%d ",location[ i++ ]) );
62             printf("%d
",location[ i ]);
63         }
64 
65         else printf("-1
");
66     }
67     return 0;
68 }
原文地址:https://www.cnblogs.com/Tree-dream/p/5748312.html