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

Labeling Balls

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11256   Accepted: 3230

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

题意:有T组测试数据,每组测试数据第一行有两个数n,m。代表有n个球,接下来m行,每行有两个数a,b,代表a球比b球轻,让你从小到大输出球的重量,若是相同重量,按照字典序输出。

思路:这个和以前的拓扑排序略微不同,不是考虑入度为0的情况。因为假设n为4,4<1.则输出的列是2,3,4,1,而不是按照以前所说的 4,1,2,3.所以要考虑的是先把最重的放在后面,轻的在前面按照字典序输出就可以了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;
int map[210][210];
int out[210];
void topo(int n)
{
    int i;
    int cnt=n;
    int weight[210];
    priority_queue<int >q;//优先队列,按照从大到小排序。
    for(i=1;i<=n;i++){
        if(out[i]==0)
            q.push(i);
    }
    while(!q.empty()){
        int k=q.top();
        q.pop();
        weight[k]=cnt--;
        for(i=1;i<=n;i++){
            if(map[i][k]){
                out[i]--;
                if(out[i]==0)
                    q.push(i);
            }
        }
    }
    if(cnt>0)
        printf("-1\n");
    else{
        for(i=1;i<n;i++)
            printf("%d ",weight[i]);
        printf("%d\n",weight[i]);
    }
}
int main()
{
    int T,n,m,i,j;
    int a,b;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        memset(out,0,sizeof(out));
        memset(map,0,sizeof(map));
        while(m--){
            scanf("%d %d",&a,&b);
            if(map[a][b]==0){
                map[a][b]=1;
                out[a]++;
            }
        }
        topo(n);
    }
    return 0;
}
时间: 2024-11-04 18:11:19

POJ 3687-Labeling Balls(逆序拓扑排序)的相关文章

poj 3687 Labeling Balls(拓补排序)

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: No two balls share the same label. The labeling satisfies several constrains like "The ball labeled with a is lighter

[ACM] POJ 3687 Labeling Balls (拓扑排序,逆向建边)

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10161   Accepted: 2810 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: No two balls share

POJ 3687:Labeling Balls(优先队列+拓扑排序)

id=3687">Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10178 Accepted: 2815 Description Windy has N balls of distinct weights from 1 unit toN units. Now he tries to label them with 1 toN in such a way that: No two balls

[ACM] POJ 3687 Labeling Balls (拓扑排序,反向生成端)

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10161   Accepted: 2810 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: No two balls share

POJ 3687 Labeling Balls【拓扑排序 优先队列】

题意:给出n个人,m个轻重关系,求满足给出的轻重关系的并且满足编号小的尽量在前面的序列 因为输入的是a比b重,但是我们要找的是更轻的,所以需要逆向建图 逆向建图参看的这一篇http://blog.csdn.net/scf0920/article/details/28108243 然后用优先队列来实现的参看的这一篇 http://ycool.com/post/u9ahrwg#algo3 1 #include<iostream> 2 #include<cstdio> 3 #includ

POJ 3687 Labeling Balls 逆向拓扑排序

链接: poj3687 题意: 有N个标号为1~N的小球,重量(不包括断言)依次增加 ,现给出M句断言 ,断言格式为a b 表示小球a轻于小球b     要求根据重量大小依次输出1~N号小球应在的的位置(重量递增)不满足断言则输出-1 题解: 因为重量是依次增加的  不能按常规的构造edge[a][b]=1生成拓扑排序 既然关系格式和一般拓扑排序是相反的  我们可以尝试着构造反向边edge[b][a]=1: indegree[a]++;   再根据小球标号从后往前进行拓扑排序,即可得到一幅完整的

POJ - 3687 Labeling Balls (拓扑排序)

题意:N个点,给出M条两个点u.v,满足u比值小.给这N个点编号,要求排在前的比排在后的质量小,且编号不重复.求每点能得到最小编号的编号方法. 分析:用拓扑排序求解. 用优先队列来存待标记的点,编号大的点优先出队列,然后从大到小依次标记(编号小的优先肯定是错的,当时wa死了). 若求不出拓扑排序则答案无解. #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #i

Labeling Balls POJ3687 【拓扑排序反向建边】【邻接表】

http://poj.org/problem?id=3687 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: No two balls share the same label. The labeling satisfies several constrains like "The

POJ 3687 Labeling Balls

题目链接:https://vjudge.net/problem/POJ-3687 题目大意 有 N 个重量互不相同的球,标记为 1 ~ N,现给定 M 个重量约束条件,将 1 ~ N 单位的重量分配给每个球,如果能成功分配,输出重量序列(字典序尽量小),不能则输出 -1. 分析 一种错误的想法是先建立拓扑图,然后拓扑排序,每次取序号最小的节点从小到大分配重量,但这是不对的,这里举个反例:5 4 · 5 1 4 2 1 3 2 3. 正解是建立逆向拓扑图,然后拓扑排序,每次取序号最大的节点从大到小