codeforces 825 E Minimal Labels
来源:互联网 发布:用户画像的数据来源 编辑:程序博客网 时间:2024/06/05 06:43
Problem
codeforces.com/contest/825/problem/E
Reference
看第 5 条评论
Meaning
给出一个n个结点的DAG,找一个给结点编号的序列,且满足3个条件:
- 编号为 1~n,每个编号出现且仅出现一次;
- 如果存在边从 f 指向 t,则结点 f 的编号要小于 t 的编号;
- 在所有可行的编号序列中,取字典序最小的;
Analysis
第二个条件就像拓扑排序,再要满足足第三个条件,就在拓扑排序时,每次从所有入度为零的点中,找出最小的点并给它当前可用的最小的编号。
然而,这样做是错的。
比如样例:
---Input---6 56 25 22 14 33 1---Outpuut---6 3 5 4 1 2
之前像上面那样写(有点像贪心),结果是:6 5 2 1 3 4
。
可能要先给某些大的点分配小的编号来“解锁”小的点,来取得更小的字典序。
按评论里给出的题解,是要反过来想,存反向边,每次也是考虑入度为零的点,但是选最大的点分配最大的编号。
评论里的证明原文(by krijgertje):
We can prove it by contradiction. Take any graph with the smallest number of nodes for which this algorithm does not give an optimal labeling. The largest label must always be assigned to a node with no outgoing edges, but it can’t be the largest of those nodes (otherwise the algorithm would give the optimal labeling). Lets call the largest node with no outgoing edges x and the node that has the largest label in the optimal labeling y. Then after labeling y with the largest label, the remaining part of the graph is correctly labeled by the algorithm (otherwise we would have a smaller graph for which the algorithm gives an incorrect result). This will first label some nodes greater than x and then it will label x. But we get a better labeling by labeling x with the largest label, y with the next largest and then label the same nodes as before. This is because of the nodes labeled so far y is the smallest node (since y < x and all other labelled nodes are greater than x) and in the partial labeling we have labeled the same nodes using the same labels. So we have a contradiction, which means our assumption was wrong and therefore there is no graph that our algorithm labels incorrectly.
Accepted Code
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>using namespace std;const int N = 100000, M = 100000;vector<int> rev[N+1]; // reverse edgeint deg[N+1]; // degree of vertexint label[N+1]; // label sequencepriority_queue<int> que;int main(){ int n, m; scanf("%d%d", &n, &m); memset(deg, 0, sizeof deg); for(int f, t, i=0; i<m; ++i) { scanf("%d%d", &f, &t); rev[t].push_back(f); ++deg[f]; } for(int i=1; i<=n; ++i) if(!deg[i]) que.push(i); for(int lab=n, t; lab > 0; --lab) // desc { t = que.top(); que.pop(); label[t] = lab; for(int i=0; i<rev[t].size(); ++i) if(--deg[rev[t][i]] == 0) que.push(rev[t][i]); } for(int i=1; i<=n; ++i) printf("%d%c", label[i], i==n?'\n':' '); return 0;}
Wrong Code
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>using namespace std;const int N = 100000, M = 100000;vector<int> g[N+1]; // edgeint deg[N+1];int label[N+1];priority_queue<int, vector<int>, greater<int> > que;int main(){ int n, m; scanf("%d%d", &n, &m); memset(deg, 0, sizeof deg); for(int f, t, i=0; i<m; ++i) { scanf("%d%d", &f, &t); g[f].push_back(t); ++deg[t]; } for(int i=1; i<=n; ++i) if(!deg[i]) que.push(i); for(int lab=1, t; lab <= n; ++lab) // ascend { t = que.top(); que.pop(); label[t] = lab; for(int i=0; i<g[t].size(); ++i) if(--deg[g[t][i]] == 0) que.push(g[t][i]); } for(int i=1; i<=n; ++i) printf("%d%c", label[i], i==n?'\n':' '); return 0;}
- codeforces 825 E Minimal Labels
- Codeforces 825E Minimal Labels
- [拓扑序] Educational Codeforces Round 25 825E. Minimal Labels
- Educational Codeforces Round 25 E. Minimal Labels
- Educational Codeforces Round 25 E. Minimal Labels
- cf 825E Minimal Labels 【拓扑】
- HDU 4857 逃生 && Codeforces 825 E. Minimal Labels 逆向拓扑序+优先队列
- Educational Codeforces Round 25 E. Minimal Labels(拓扑排序)
- Educational Codeforces Round 25E. Minimal Labels(拓扑排序+思维)
- codeforce 825E. Minimal Labels 拓扑排序 贪心思想
- Codeforces 825 F Minimal Labels(反向拓扑排序)
- CF-Educational-25 E-Minimal Labels (拓扑排序,字典序)
- codeforces825E Minimal Labels【拓扑排序】
- CF825E:Minimal Labels(拓扑排序)
- E - Minimal Ratio Tree
- codeforces 825E(拓扑)
- Minimal string CodeForces
- Codeforces 797C-Minimal string
- java迭代器(Itreator)
- learning之组合模式
- HDU1262-寻找素数对
- Java--异常处理机制
- mybatis 嵌套的结果集不能被安全的转为自定义ResultHandler 的解决办法
- codeforces 825 E Minimal Labels
- JAVA文件处理类
- 二叉树中两个节点的最近公共祖先节点
- gcc与g++的区别
- 用Unity做游戏,你需要深入了解一下IL2CPP
- 解决百度地图反复进出偶尔会崩溃的问题
- springboot整合redis,注解方式
- 使用js实时显示北京时间
- C++中友元详解