题目链接:点击打开链接

题意:

给定n个点 m条边的无向图 须要在图里添加p条边 使得图最后连通分量数为q

问是否可行,不可行输出NO

可行输出YES,并输出加入的p条边。

set走起。。

  1. #include<stdio.h>
  2. #include<iostream>
  3. #include<string.h>
  4. #include<algorithm>
  5. #include<vector>
  6. #include<set>
  7. using namespace std;
  8. #define N 123456
  9.  
  10. #define ll __int64
  11. ll n,m,p,q;
  12. struct Edge{
  13. ll from, to, dis;
  14. }edge[N*2];
  15. ll edgenum;
  16. void add(ll u,ll v,ll dis){
  17. Edge E={u,v,dis};
  18. edge[edgenum++] = E;
  19. }
  20. ll f[N];
  21. ll find(ll x){return x==f[x]?x:f[x]=find(f[x]);}
  22. void Union(ll x,ll y){
  23. ll fx = find(x), fy = find(y);
  24. if(fx==fy)return ;
  25. if(fx<fy)swap(fx,fy);
  26. f[fx]=fy;
  27. }
  28. set<ll>myset;
  29. set<ll>::iterator pp;
  30. ll siz[N];
  31. vector<int>L,R;
  32. struct node{
  33. ll fa, val;
  34. bool operator<(const node&x)const{
  35. if(x.val==val)return x.fa<fa;
  36. return x.val>val;
  37. }
  38. node(ll x=0,ll y = 0):fa(x),val(y){}
  39. };
  40. set<node>hehe;
  41. set<node>::iterator dd;
  42. void init(){
  43. hehe.clear();
  44. L.clear(); R.clear();
  45. memset(siz, 0, sizeof siz);
  46. myset.clear();
  47. for(ll i = 1; i <= n; i++)f[i]=i;
  48. edgenum = 0;
  49. }
  50.  
  51. void go(){
  52. dd = hehe.begin();
  53. node x = *dd;
  54. hehe.erase(dd);
  55. dd = hehe.begin();
  56. node y = *dd;
  57. hehe.erase(dd);
  58. Union(x.fa,y.fa);
  59. ll now = min((ll)1000000000, x.val+y.val+1);
  60. node z = node(find(x.fa),x.val+y.val+now);
  61. hehe.insert(z);
  62. L.push_back(x.fa); R.push_back(y.fa);
  63. add(x.fa,y.fa,1);
  64. }
  65. int main(){
  66. ll i, j, u, v, d;
  67. while(~scanf("%I64d %I64d %I64d %I64d",&n,&m,&p,&q)){
  68. init();
  69. while(m--){
  70. scanf("%I64d %I64d %I64d",&u,&v,&d);
  71. add(u,v,d);
  72. Union(u,v);
  73. }
  74. for(i = 1; i <= n; i++)find(i);
  75. for(i = 1; i <= n; i++)myset.insert(f[i]);
  76. for(i = 0; i < edgenum; i++){
  77. siz[f[edge[i].from]]+=edge[i].dis;
  78. }
  79. if(myset.size()<q){puts("NO");continue;}
  80. if(myset.size()==q)
  81. {
  82. if(p && edgenum==0)puts("NO");
  83. else
  84. {
  85. puts("YES");
  86. while(p--){
  87. cout<<edge[0].from<<" "<<edge[0].to<<endl;
  88. }
  89. }
  90. continue;
  91. }
  92. ll ned = myset.size()-q;
  93. if(ned>p){puts("NO");continue;}
  94. p-=ned;
  95.  
  96. for(pp=myset.begin(); pp!=myset.end(); pp++)hehe.insert(node(*pp,siz[*pp]));
  97. while(ned--)go();
  98.  
  99. puts("YES");
  100. for(i = 0; i < L.size(); i++)cout<<L[i]<<" "<<R[i]<<endl;
  101. while(p--)
  102. cout<<edge[0].from<<" "<<edge[0].to<<endl;
  103. }
  104. return 0;
  105. }

Codeforces 362D Fools and Foolproof Roads 构造题的更多相关文章

  1. Codeforces 362D Fools and Foolproof Roads

    Fools and Foolproof Roads 并查集瞎搞搞就行, 有点小坑点. #include<bits/stdc++.h> #define LL long long #defin ...

  2. Codeforces Round #212 (Div. 2) D. Fools and Foolproof Roads 并查集+优先队列

    D. Fools and Foolproof Roads   You must have heard all about the Foolland on your Geography lessons. ...

  3. Codeforces 1491G - Switch and Flip(构造题)

    Codeforces 题目传送门 & 洛谷题目传送门 obviously,难度高一点的构造题对我来说都是不可做题 首先考虑将排列拆成一个个置换环,也就是 \(\forall i\) 连边 \( ...

  4. Educational Codeforces Round 7 D. Optimal Number Permutation 构造题

    D. Optimal Number Permutation 题目连接: http://www.codeforces.com/contest/622/problem/D Description You ...

  5. Codeforces 191C Fools and Roads(树链拆分)

    题目链接:Codeforces 191C Fools and Roads 题目大意:给定一个N节点的数.然后有M次操作,每次从u移动到v.问说每条边被移动过的次数. 解题思路:树链剖分维护边,用一个数 ...

  6. B - Save the problem! CodeForces - 867B 构造题

    B - Save the problem! CodeForces - 867B 这个题目还是很简单的,很明显是一个构造题,但是早训的时候脑子有点糊涂,想到了用1 2 来构造, 但是去算这个数的时候算错 ...

  7. Codeforces 482 - Diverse Permutation 构造题

    这是一道蛮基础的构造题. - k         +(k - 1)      -(k - 2) 1 + k ,    1 ,         k ,             2,    ....... ...

  8. CodeForces 297C Splitting the Uniqueness (脑补构造题)

    题意 Split a unique array into two almost unique arrays. unique arrays指数组各个数均不相同,almost unique arrays指 ...

  9. Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换

    A 直接判存不存在连续的三个包含A,B,C就行 /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a ...

随机推荐

  1. ASP.NET实现文件下载

    转:http://blog.csdn.net/codeshark/article/details/2473664 方式一:TransmitFile实现下载.将指定的文件直接写入 HTTP 响应输出流, ...

  2. Linux sed命令删除指定行

    一.删除包含匹配字符串的行## 删除包含baidu.com的所有行sed -i '/baidu.com/d' domain.file 二.删除匹配行及后所有行## 删除匹配20160229的行及后面所 ...

  3. CompareValidator ASP控件

    定义和用法 CompareValidator 控件用于将由用户输入到输入控件的值与输入到其他输入控件的值或常数值进行比较. 注释:如果输入控件为空,则不会调用任何验证函数,并且验证将成功.使用 Req ...

  4. [转]MySQL导入和导出SQL脚本

    首先,使用mysqldump命令的前提是,在Cmd中进入mysql安装目录下的bin目录下,才可以使用该命令.我的mysql安装在E:盘,所以,首先进入bin目录下:E:/Program Files/ ...

  5. UVA 10131 - Is Bigger Smarter? (动态规划)

    Is Bigger Smarter? The Problem Some people think that the bigger an elephant is, the smarter it is. ...

  6. 理解javascript之 对象

    大纲: 1.介绍attribute property的异同,翻译自http://javascript.info/tutorial/attributes-and-custom-properties#pr ...

  7. bash shell学习-shell script基础 (笔记)

    A chain no stronger than its weakest link. "一着不慎,满盘皆输" 参考资料:鸟哥的Linux私房菜 基础学习篇(第三版)  Linux ...

  8. ActionResult派生类

    类名 抽象类 父类 功能 ContentResult 根据内容的类型和编码,数据内容. EmptyResult 空方法. FileResult abstract 写入文件内容,具体的写入方式在派生类中 ...

  9. PHP分页详细讲解

    网上有好多PHP分页的类,但我们要弄明白PHP分页原理才可以学到知识,今天我就带你学制作PHP分页.     1.前言分页显示是一种非常常见的浏览和显示大量数据的方法,属于web编程中最常处理的事件之 ...

  10. Python学习笔记四--字典与集合

    字典是Python中唯一的映射类型.所谓映射即指该数据类型包含哈希值(key)和与之对应的值(value)的序列.字典是可变类型.字典中的数据是无序排列的. 4.1.1字典的创建及赋值 dict1={ ...