POJ 3687 Labeling Balls(特殊的拓扑排序)

题目链接: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:

  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

题意:给定n个编号从1-n的球,m个关系:a b(代表标号为a的球比编号为b的球轻),最后要求输出每个编号的球对应的重量,并且前面编号的球的重量要尽可能小。

题解:逆向建图,把轻的球给予入度(这里可以认为是让重球先出来),然后从n-1标号给予重球,标记即可。

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 using namespace std;
 6
 7 const int N=2222;
 8 int n,m;
 9 int in[N],ans[N];
10 bool E[N][N];
11 queue <int> Q;
12
13 bool toposort(){
14     while(!Q.empty()) Q.pop();
15     for(int i=n;i>=1;i--){//代表位置,倒序找最大的
16         int cnt=0,idx;
17         for(int j=1;j<=n;j++){//代表球的重量,找球的重量最大的
18             if(in[j]==0) cnt++,idx=j;
19         }
20         if(cnt==0) return false;
21         ans[idx]=i;
22         in[idx]--;
23         for(int k=1;k<=n;k++){
24             if(E[idx][k]) in[k]--;
25         }
26     }
27     return true;
28 }
29
30
31 int main(){
32
33     int t;
34     scanf("%d",&t);
35     while(t--){
36         memset(E,0,sizeof(E));
37         memset(in,0,sizeof(in));
38         scanf("%d%d",&n,&m);
39         //反向建图
40         for(int i=1;i<=m;i++){
41             int a,b;
42             scanf("%d%d",&a,&b);
43             if(!E[b][a]){
44                 E[b][a]=1;
45                 in[a]++;
46             }
47         }
48         if(!toposort()) printf("-1\n");
49         else{
50             for(int i=1;i<=n;i++){
51                 if(i!=n) printf("%d ",ans[i]);
52                 else printf("%d\n",ans[i]);
53             }
54         }
55     }
56
57     return 0;
58 }

原文地址:https://www.cnblogs.com/Leonard-/p/8456186.html

时间: 2024-10-08 10:19:16

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. 正解是建立逆向拓扑图,然后拓扑排序,每次取序号最大的节点从大到小