POJ-3687-Labeling Balls

来源:互联网 发布:服务器与域名的关系 编辑:程序博客网 时间:2024/06/01 09:37
Labeling Balls
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 14167 Accepted: 4117

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 integers a and b indicating the ball labeled witha must be lighter than the one labeled with b. (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

54 04 11 14 21 22 14 12 14 13 2

Sample Output

1 2 3 4-1-12 1 3 41 3 2 4

Source

POJ Founder Monthly Contest – 2008.08.31, windy7926778



解题思路:
    将输入的n行建立有向图,如果该图产生回路,那么输出-1,如果不产生回路,重量 从高到低依次选择可以选择的最大编号
    每次找出入度为0的点,为了防止重复计算,入度为0的点也要--;这样就为-1了。
    每次找,最后输出就可以了
    两组比较好的测试案例:
    第二个测试案例有5个,但是有2个一样的,所以按 4 个算

C++ 源代码

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;const int MAX = 210;int map[MAX][MAX],indegree[MAX],ans[MAX];int n,m;int main(){    int i,j,k;    int u,v;    int t;    cin>>t;    while(t--)    {        scanf("%d %d",&n,&m);        memset(map,0,sizeof(map));        memset(indegree,0,sizeof(indegree));        for(i=0;i<m;i++)        {            scanf("%d %d",&u,&v);            if(!map[v][u])      //反向建图            {                map[v][u]=1;                indegree[u]++;            }        }        for(i=n;i>=1;i--)    //i 表示重量 从高到低依次选择可以选择的最大编号        {            for(j=n;j>=1;j--)  //j 表示每次可能选出的(即出度为0)最大编号,那么该编号一定能够排在其他所有编号的后边,            {                   //找出度为0的最大编号使其分配最大的重量,那么最后找出的解一定是最优解。                if(indegree[j]==0)                {                    indegree[j]--;                    ans[j]=i;                    for(k=1;k<=n;k++)                        if(map[j][k]==1)                            indegree[k]--;                        break;                }            }            if(j<1)                break;        }        if(i>=1)            cout<<"-1\n";        else        {            for(i=1;i<n;i++)                cout<<ans[i]<<" ";            cout<<ans[n]<<endl;        }    }    return 0;  }


0 0
原创粉丝点击