• Poj 3687 -- Labeling Balls


    Labeling Balls
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 9070   Accepted: 2451

    Description

    Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N 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 with b".

    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 next M line each contain two integers a and b indicating the ball labeled with a must be lighter than the one labeled with b. (1 ≤ a, b ≤ N) 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 label N. 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


    思路:这是一道很有意思的题。由于今天刚接触拓扑排序,所以做这个题感觉非常非常吃力。之所以说他有意思,是因为这个题灵活性很大,
    除了要逆向建图,还需要注意很多地方,比如说输出的是球的重量和重边问题等等。可以举个例子来说明我的思路:
    5 4
    5 1
    4 2
    1 3
    2 3
    给出这组数据:用一数组标记是否重边,且用数组建立数与数之间的联系。比如输入a,b拿后面两对 1 3 2 3,可以令s[1][3]=1.s[2][3]=1
    这样不仅可以标记已经存在,还可以说明3 与1 2存在关系。然后in[a]++, in[]表示入度。
    然后就可以建图了。不断寻找入度为零的数加进优先队列,每出一个元素,与它有联系的元素的入度均减一,出去的这个元素重量肯定是最大的,然后再找入度为零的元素进队列
    再出队列。此元素(即球的标号)的重量是第二大的。不断进出直到队列为空。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <queue>
     5 using namespace std;
     6 int in[250],s[250][250],weight[250];
     7 void slove(int n)
     8 {
     9     priority_queue<int>que;
    10     int i,g=n;
    11     for(int i=1; i<=n; i++){
    12         if(in[i]==0) que.push(i);
    13     }
    14     while(!que.empty()){
    15         int t=que.top();
    16         weight[t]=g--;
    17         que.pop();
    18         for(int i=1; i<=n; i++){
    19             if(s[t][i] && --in[i]==0){
    20                 que.push(i);
    21             }
    22         }
    23     }
    24     for(i=1; i<=n; i++){
    25         if(!weight[i]){
    26             printf("-1
    ");
    27             break;
    28         }
    29     }
    30     if(i<=n) return ;
    31     int flag=0;
    32     for(int i=1; i<=n; i++){
    33         if(flag) printf(" ");
    34         printf("%d",weight[i]);
    35         flag=1;
    36     }
    37     printf("
    ");
    38 }
    39 int main()
    40 {
    41     int cas,n,m,a,b;
    42     scanf("%d",&cas);
    43     while(cas--){
    44         memset(s,0,sizeof(s));
    45         memset(in,0,sizeof(in));
    46         memset(weight,0,sizeof(weight));
    47         scanf("%d%d",&n,&m);
    48         for(int i=0; i<m; i++){
    49             scanf("%d%d",&a,&b);
    50             if(!s[b][a]){
    51                 s[b][a]=1;
    52                 in[a]++;
    53             }
    54         }
    55         slove(n);
    56     }
    57     return 0;
    58 }





    Do one thing , and do it well !
  • 相关阅读:
    模板的一些概念和技巧
    [转] Linux TCP/IP网络小课堂:net-tools与iproute2大比较
    [转] boost库的Singleton的实现以及static成员的初始化问题
    static对象的高级用法
    const中的一些tricky的地方
    delphi软件启动的顺序解密。
    属性名、变量名与 内部关键字 重名 加&
    delphi Inc函数和Dec函数的用法
    Centos 关闭防火墙
    IntelliJ IDEA 启动方法
  • 原文地址:https://www.cnblogs.com/ubuntu-kevin/p/3226475.html
Copyright © 2020-2023  润新知