POJ 3687Labeling Balls(逆序拓扑排序)

Labeling Balls

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14115   Accepted: 4101

Description

Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 toN in such a way that:

  1. No two balls share the same label.
  2. The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled withb".

Can you help windy to find a solution?

Input

The first line of input is the number of test case. The first line of each test case contains two integers,N (1 ≤N ≤ 200) and M (0 ≤ M ≤ 40,000). The nextM line each contain two integersa and b indicating the ball labeled witha must be lighter than the one labeled withb. (1 ≤ a, bN) There is a blank line before each test case.

Output

For each test case output on a single line the balls' weights from label 1 to labelN. If several solutions exist, you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest weight for label 3 and so on... If no solution exists, output -1 instead.

Sample Input

5

4 0

4 1
1 1

4 2
1 2
2 1

4 1
2 1

4 1
3 2

Sample Output

1 2 3 4
-1
-1
2 1 3 4
1 3 2 4

题意:给定两个数,一个是球的个数,一个是两球的轻重关系a,b,a比b重,输出从1号到n号他们的从轻到重的排行。

题解:因为a比b重,所以b->a,要从重的逆序进行拓扑排序,是为了保证重的尽量是大的号码,轻的尽量是轻的号码。

#include 
#include 
#include 
using namespace std;

int Map[250][250];
int in[250];
int s[250];
int main()
{
    int K, i, j, n, m, x, y, k;
    scanf("%d",&K);
    while(K--)
    {
        memset(Map, 0, sizeof(Map));
        memset(in, 0, sizeof(in));
        scanf("%d %d",&n, &m);
        for(i = 0; i < m; i++)
        {
            scanf("%d%d",&x, &y);
            if(!Map[y][x])
            {
                Map[y][x] = 1;
                in[x] ++;
            }

        }
        int flag = 0;
        for(i = n; i >= 1; i --)
        {
            for(j = n; j >= 1; j --)
            {
                if(in[j] == 0)
                {
                    in[j] = -1;
                    s[j] = i;
                    for(k = 1; k <= n; k ++)
                    {
                        if(Map[j][k] == 1)
                        {
                            in[k] --;
                        }
                    }
                    break;
                }
            }
            if(j < 1)
            {
                flag = 1;
                break;
            }

        }
        if(flag == 1)
            printf("-1\n");
        else
        {
            for(i = 1; i < n; i++)
            {
                printf("%d ",s[i]);
            }
            printf("%d\n",s[n]);
        }
    }
    return 0;
}
//逆序拓扑的做法


你可能感兴趣的:(POJ初级)