ACM/ICPC 之 拓扑排序-反向(POJ3687)

难点依旧是题意。。。。需要反向构图+去重+看题



POJ3687-Labeling Balls

  题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重量最轻,若依旧多组则输出编号次小的Ball重量最轻的方案。

  题解:在看懂题意后,再开始做会省很多时间。。。曲解题意还真是人类的本能啊。

     为了完成单向关系排序,需要用到拓扑排序

     为了符合编号最小的重量最轻...的题意,需要用到反向拓扑排序

     输入可能会有重复的关系,因此需要判重

     输出需要按原编号输出其重量,因此需要在每个编号上标记其重量

 1 //给球编号
 2 //1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号越小重量越轻的方案
 3 //反向拓扑+去重+看题...(题意最后需要将Ball的重量按原编号输出)
 4 //迭代器判重:Time:125Ms    Memory:524K
 5 //数组判重:  Time:63Ms    Memory:564K
 6 #include<iostream>
 7 #include<cstring>
 8 #include<cstdio>
 9 #include<vector>
10 using namespace std;
11
12 #define MAX 205
13
14 struct Number {
15     vector<int>    light;
16     int in;        //in_degree
17     int weight;    //该编号球的重量
18 }num[MAX];
19
20 int n, m;
21 bool v[MAX][MAX];
22
23 bool TopSort()
24 {
25     for (int t = n; t > 0; t--)    //最重到最轻
26     {
27         int cur = n + 1;
28         while (--cur && num[cur].in);    //将最大的label先取出放在最后
29         if (cur == 0) return false;    //有环
30
31         num[cur].weight = t;    //记录重量
32         num[cur].in--;
33         for (unsigned j = 0; j < num[cur].light.size(); j++)
34             num[num[cur].light[j]].in--;
35     }
36     return true;
37 }
38
39 int main()
40 {
41     int T;
42     scanf("%d", &T);
43     while (T--)
44     {
45         memset(num, 0, sizeof(num));
46         memset(v, false, sizeof(v));
47         scanf("%d%d", &n, &m);
48         for (int i = 0; i < m; i++)
49         {
50             int light, heavy;
51             scanf("%d%d", &light, &heavy);
52             //反向构图
53             //迭代器判重
54             //vector<int> lg = num[heavy].light;
55             //if (find(lg.begin(), lg.end(), light) != lg.end())    continue;
56             //数组判重
57             if (v[heavy][light]) continue;
58             v[heavy][light] = true;
59             num[heavy].light.push_back(light);
60             num[light].in++;
61         }
62
63         if (TopSort())
64         {
65             for (int i = 1; i < n; i++)
66                 printf("%d ", num[i].weight);
67             printf("%d\n", num[n].weight);
68         }
69         else printf("-1\n");
70
71     }
72
73     return 0;
74 }
时间: 2024-08-28 03:48:17

ACM/ICPC 之 拓扑排序-反向(POJ3687)的相关文章

ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083))

经典的拓扑排序问题,难点在于字典序输出和建立拓扑图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacking 题意:每个图片由同一字母组成的边框表示,每个图片的字母都不同: 在一个最多30*30的区域放置这些图片,问底层向顶层叠加的图片次序,多选时按字典序输出 注:每个图片的四边都会有字符显示,其中顶点显示两边. 题解:题意的理解是难点,题目对图片的范围确定说得有点含糊不清,博主一开始就被出现的五张图片的样例迷惑,理解重心放错了.题目最需要理解的是

HDU2647(拓扑排序+反向建图)

题意不说了,说下思路. 给出的关系是a要求的工资要比b的工资多,由于尽可能的让老板少付钱,那么a的工资就是b的工资+1,可以确定关系为a>b,根据拓扑排序建边的原则是把"小于"关系看成有向边,那么我们可以建边v->u. #include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <algorithm> #

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

ACM: hihicoder #1174 : 拓扑排序&#183;一 STL- queue

#1174 : 拓扑排序·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来. 小Ho:小Hi,你这学期有选什么课么? 小Hi:挺多的,比如XXX1,XXX2还有XXX3.本来想选YYY2的,但是好像没有先选过YYY1,不能选YYY2. 小Ho:先修课程真是个麻烦的东西呢. 小Hi:没错呢.好多课程都有先修课程,每次选课之前都得先查查有没有先修.教务公布的先修课程记录都是好多年前的,不但有重复的信息,好像

关于拓扑排序的一些想法

前几天数据结构课上老师给我们留了一道思考题:如何求出拓扑排序的所有可能路径.说实话,自己的第一感觉就是深搜DFS,但是到最后又被自己推翻了,本来周三的时候想到了一个算法,后来又被自己推翻了.在BestCoder群里问了几个大神,他们也没给出什么好的方法,印象深刻的是有人说我问这种题有意义吗,问得我竟然无法反驳,也是,大多数的人总是要为自己的无知做一些辩解. 后来整理了一下自己之前所想的,虽然有很大一个漏洞(这就是我推翻我算法的原因),不过自己所想到的算法自己都用代码实现了,也算是一件成功的事情.

ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TshingHua OJ-旅行商TSP)

做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(TSP) Description Shrek is a postman working in the mountain, whose routine work is sending mail to n villages. Unfortunately, road between villages is

POJ3687 反向拓扑排序

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16032   Accepted: 4713 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

HDU 5438 Ponds (拓扑排序+DFS)2015 ACM/ICPC Asia Regional Changchun Online

[题目链接]:click here~~ [题目大意]: 题意:在一个无向图中有 p 个点, m 条边,每个点有一个值 vi .不断的删去度数小于2的点直到不能删为止.求新图中所有点个数为奇数的连通分量的点值的和. 1<p<10^4,1<m<10^5 [思路]删边考虑类似拓扑排序的写法,不过topsort是循环一遍1到n结点入度为0的结点,然后加入到队列中,这里只要改一下度数小于等于1,最后DFS 判断一下 挫挫的代码: /* * Problem: HDU No.5438 * Run

[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