D. Gourmet choice

链接:http://codeforces.com/contest/1131/problem/D

思路: =  的情况我们用并查集把他们扔到一个集合,然后根据 > < 跑拓扑排序,根据拓扑排序的结果从小到大填数字就好了,需要注意的细节写在代码注释里了

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int M = 2e3+;
  4. int f[M],n,m;
  5. set<int>st[M];
  6. vector<int>v;
  7. int vis[M];
  8. map<int,int>ans;
  9. bool flag;
  10. string g[M];
  11. int in[M];
  12. int Find(int x){
  13. if(x == f[x]) return x;
  14. return f[x] = Find(f[x]);
  15. }
  16.  
  17. int Union(int x,int y){
  18. int fx = Find(x);
  19. int fy = Find(y);
  20. if(fx != fy) f[fx] = fy;
  21. }
  22.  
  23. void Toposort(){
  24. queue<int>q;
  25. for(int i = ;i < n+m;i ++){
  26. //同一个集合内的数如果之前已经出现过就跳过
  27. if(vis[Find(i)]==) continue;
  28. if(in[Find(i)] == ){
  29. q.push(Find(i));
  30. vis[Find(i)]=;
  31. }
  32. }
  33. //因为要计数,所以多开一个vector存每一轮入度为0的点
  34. int cnt = ;
  35. while(!q.empty()){
  36. v.clear();
  37. while(!q.empty()){
  38. v.push_back(q.front());
  39. q.pop();
  40. }
  41. for(auto &i : v){
  42. ans[i] = cnt;
  43. for(auto &j : st[i]){
  44. if(vis[j]==) continue;
  45. in[j]--;
  46. if(in[j] == ){
  47. q.push(j);
  48. vis[j]=;
  49. }
  50. }
  51. }
  52. cnt ++;
  53. }
  54. }
  55.  
  56. int main()
  57. {
  58. cin>>n>>m;
  59. flag = ;
  60. for(int i = ;i < n+m;i ++) f[i] = i;
  61. for(int i = ;i < n;i ++){
  62. cin>>g[i];
  63. for(int j = ;j < m;j ++){
  64. if(g[i][j] == '='){
  65. if(Find(i) != Find(n+j))
  66. Union(i,n+j);
  67. }
  68. }
  69. }
  70. for(int i = ;i < n;i ++){
  71. for(int j = ;j < m;j ++){
  72. if(g[i][j] == '=') continue;
  73. int x = Find(i),y = Find(n+j);
  74. if(x == y) flag = ;
  75. if(g[i][j] == '>') swap(x,y);
  76. if(st[x].find(y) == st[x].end()){
  77. st[x].insert(y);
  78. in[y]++;
  79. }
  80. }
  81. }
  82. //如果一个集合内出现>或<,那么自相矛盾,输出No
  83. if(!flag){
  84. cout<<"No"<<endl;
  85. return ;
  86. }
  87. Toposort();
  88. //如果两个数 < > 关系矛盾,也就是i出现x>y且x<y,那么双方入度都无法为0,无法取值,
  89. //所以如果值为0那么代表出现矛盾的情况输出N0
  90. for(int i = ;i < n+m;i ++){
  91. if(ans[Find(i)] == )
  92. flag = ;
  93. }
  94. if(flag){
  95. cout<<"Yes"<<endl;
  96. for(int i = ;i < n;i ++)
  97. cout<<ans[Find(i)]<<" ";
  98. cout<<endl;
  99. for(int i = n;i < n+m;i ++)
  100. cout<<ans[Find(i)]<<" ";
  101. cout<<endl;
  102. }
  103. else cout<<"No"<<endl;
  104. return ;
  105. }

F. Asya And Kittens

链接:http://codeforces.com/contest/1131/problem/F

思路:很容易发现房间合并的过程非常像并查集集合的合并,但是并查集合并并不能得到一段序列,所以我们用一个nex数组储存数字的前后关系,并用last数组记录集合最后的那个数,两个集合合并时,左边集合最后那个数的nex就是右边集合的第一个数,合并后整个集合的last就是右边集合的last,这样维护好两个数组,最后遍历一遍nex数组就可以得到一段符合要求的序列了。

实现代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int M = 2e5+;
  4. int f[M],nex[M],last[M];
  5. int Find(int x){
  6. if(x == f[x]) return x;
  7. return f[x] = Find(f[x]);
  8. }
  9.  
  10. int Union(int x,int y){
  11. int fx = Find(x);
  12. int fy = Find(y);
  13. if(fx != fy) f[fy] = fx;
  14. }
  15.  
  16. int main()
  17. {
  18. int n,a,b;
  19. cin>>n;
  20. for(int i = ;i <= n;i ++)
  21. last[i]=f[i]=i;
  22. for(int i = ;i <= n-;i ++){
  23. cin>>a>>b;
  24. int fx = Find(a);
  25. int fy = Find(b);
  26. nex[last[fx]] = fy;
  27. last[fx] = last[fy];
  28. Union(a,b);
  29. }
  30. for(int i = Find();i;i=nex[i])
  31. cout<<i<<" ";
  32. return ;
  33. }

Codeforces Round #541 (Div. 2) D(并查集+拓扑排序) F (并查集)的更多相关文章

  1. Codeforces Round #292 (Div. 1) B. Drazil and Tiles 拓扑排序

    B. Drazil and Tiles 题目连接: http://codeforces.com/contest/516/problem/B Description Drazil created a f ...

  2. Codeforces Round #285 (Div. 1) A. Misha and Forest 拓扑排序

    题目链接: 题目 A. Misha and Forest time limit per test 1 second memory limit per test 256 megabytes 问题描述 L ...

  3. Codeforces Round #292 (Div. 2) D. Drazil and Tiles [拓扑排序 dfs]

    传送门 D. Drazil and Tiles time limit per test 2 seconds memory limit per test 256 megabytes Drazil cre ...

  4. Codeforces Round #660 (Div. 2) Captain Flint and Treasure 拓扑排序(按照出度、入读两边拓扑排序)

    题目链接:Captain Flint and Treasure 题意: 一种操作为 选一个下标 使得ans+=a[i] 且 把a[b[i]]+a[i]   要求每个下标都进行一种这样的操作,问怎么样的 ...

  5. Codeforces Round #541 (Div. 2)

    Codeforces Round #541 (Div. 2) http://codeforces.com/contest/1131 A #include<bits/stdc++.h> us ...

  6. Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序

    https://codeforces.com/contest/1131/problem/D 题意 给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[] ...

  7. Codeforces Round #396 (Div. 2) A B C D 水 trick dp 并查集

    A. Mahmoud and Longest Uncommon Subsequence time limit per test 2 seconds memory limit per test 256 ...

  8. Codeforces Round #541 (Div. 2) (A~F)

    目录 Codeforces 1131 A.Sea Battle B.Draw! C.Birthday D.Gourmet choice(拓扑排序) E.String Multiplication(思路 ...

  9. Codeforces 1131 F. Asya And Kittens-双向链表(模拟或者STL list)+并查集(或者STL list的splice()函数)-对不起,我太菜了。。。 (Codeforces Round #541 (Div. 2))

    F. Asya And Kittens time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

随机推荐

  1. Python_迭代器_35

    迭代器 # l = [1,2,3]# 索引# 循环 for# for i in l:# i## for k in dic:# pass #可以被for循环的# list# dic# str# set# ...

  2. 软件工程(FZU2015) 赛季得分榜,第二回合

    SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...

  3. HDFS的命令

    .....Hdfs dfs -cat path hadoop fs - 等同 1 -ls 查看当前目录的文件和文件夹 2 -lsr 递归查看 3 -du 查看文件的大小 4-dus 查看文件夹中所有的 ...

  4. Es5中的类和静态方法 继承

    Es5中的类和静态方法 继承(原型链继承.对象冒充继承.原型链+对象冒充组合继承) // es5里面的类 //1.最简单的类 // function Person(){ // this.name='张 ...

  5. CentOS 7 安装配置带用户认证的squid代理服务器

    这里只简述搭建一个带用户认证的普通代理 一.安装 安装过程十分简便,只需要安装一下squid,一条命令搞定 yum install squid rpm -qa | grep squid squid-- ...

  6. vue嵌套路由

    父组件  (注:to="/Flow/moban_a"这里不是文件加路径,是父组件路由+子组件路由) 路由配置

  7. day 7-7 线程池与进程池

    一. 进程池与线程池 在刚开始学多进程或多线程时,我们迫不及待地基于多进程或多线程实现并发的套接字通信,然而这种实现方式的致命缺陷是:服务的开启的进程数或线程数都会随着并发的客户端数目地增多而增多,这 ...

  8. druid 连接Oracle时出现的错误

    转博主https://blog.csdn.net/jiangyu1013/article/details/70237550#commentsedit mysql 更新 SQL 语句 无错误 批量 报错 ...

  9. 设计模式笔记:开闭原则(OCP,The Open-Closed Principle)

    1. 开闭原则概述 开闭原则(OCP,The Open-Closed Principle)两个主要特征: (1)对扩展开放(open for extension):模块的行为的可以扩展的,当应用的需求 ...

  10. 老男孩python学习自修第六天【pycharm的使用】

    1.在工程右键可选新建文件夹,包盒python文件 文件夹和包的区别在于,包包含一个空的__init__.py文件,而文件夹没有 2.pycharm的断点调试 点击Debug表示进入调试状态 点击Re ...