博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bzoj 3624: [Apio2008]免费道路 (贪心+生成树)
阅读量:6241 次
发布时间:2019-06-22

本文共 2047 字,大约阅读时间需要 6 分钟。

Sample Input

5 7 2
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1

Sample Output

3 2 0
4 3 0
5 3 1
1 2 1
  这道题当时光读题就读半天,现在大概翻译一下:
    我们需要对于该图建一棵生成树使所有点连通,并且这棵树里有且只有K条白边。
   读明白后就想到了[国家集训队2012]tree(陈立杰),那道题也是类似,要求白边数量恰好为need,但是那道题要求是最小生成树,而这道题只要是生成树就好了。而且还得判断和不合法。然后就开始想,假设我们先扣掉所有白边,那么剩下的就是由黑边组成的一个个联通块了。然后呢?就不知道了,一开始想去用并查集搞,但是没搞出什么名堂,也就放弃了。
  正解的确还是最小生成树,额,或许不应该说是最小生成树,但是的确要用克鲁斯卡尔,我们先把黑边优先,这样,我们就可以先找出造出一个生成树的下限,如果k比他还小那么显然不行。同理,我们再白边优先,找出生成树的上限,如果k比他大那么仍然不行。
  合法性我们解决完了,答案怎么出来呢?
  让我们先回顾树的一个性质:当我们在一棵树上,从一个点向另一个点连边时树就会被破坏,但是,当我们拆开由这两个边组成的环上的任意一点时,树又变得合法。
  首先,对于我们找出白边下限时找出的白边我们都是无法找出黑边将他们替换的,说白了,我们必须选上他们。
  其次,对于剩下的白边,我们可以意识到,我们之所以没有把它们在找下限时把它找到是因为它可以被一个黑边或者白边代替,如果它被白边代替,那么我们仍然不必选他,因为那条白边是一定要选的,当然,我们可以把它和那条白边替换,但既然是spj,这有什么意义呢?
   如果他是被黑边替换,那么我们如果先选他也就不必再去选那条黑边,因此,我们先把必须选白边选上,再贪心去找那些被黑边替换的白边,找够了就只去找黑边,最终输出答案就好了。
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #define N 20005 10 #define M 100005 11 using namespace std; 12 int n,m,t,fa[N]; 13 struct ro 14 { 15 int to,from,l; 16 bool bj; 17 }road[M]; 18 bool px1(ro a,ro b) 19 { 20 return a.l>b.l; 21 } 22 bool px2(ro a,ro b) 23 { 24 return a.l
t) 65 { 66 printf("no solution\n"); 67 exit(0); 68 } 69 sort(road+1,road+1+m,px2); 70 js1=0,js2=0; 71 for(int i=1;i<=n;i++)fa[i]=i; 72 for(int i=1;i<=sum;i++) 73 { 74 if(road[i].bj) 75 { 76 int x=road[i].from,y=road[i].to; 77 hb(x,y); 78 js2++; 79 js1++; 80 ans[js1]=i; 81 } 82 } 83 for(int i=1;i<=m;i++) 84 { 85 int x=road[i].from,y=road[i].to; 86 if(find(x)!=find(y)) 87 { 88 if(!road[i].l) 89 { 90 js2++; 91 } 92 js1++; 93 ans[js1]=i; 94 hb(x,y); 95 } 96 if(js2==t)i=sum,js2=-1; 97 } 98 if(js2!=-1) 99 {100 printf("no solution\n");101 exit(0);102 }103 for(int i=1;i<=n-1;i++)104 {105 printf("%d %d %d\n",road[ans[i]].from,road[ans[i]].to,road[ans[i]].l);106 }107 return 0;108 }
View Code

转载于:https://www.cnblogs.com/liutianrui/p/7652760.html

你可能感兴趣的文章
我的友情链接
查看>>
文本统计命令——wc
查看>>
mina2.0
查看>>
JEESZ简介
查看>>
Linux中通过/proc/stat等文件计算Cpu使用率(一)
查看>>
Centos6.5下利用rsyslog+loganalyzer+mysql部署日志服务器
查看>>
Linux查看硬件信息的一些命令
查看>>
基于VMware vSphere 5.0的服务器虚拟化实践(2)
查看>>
MySQL学习笔记_6_SQL语言的设计与编写(下)
查看>>
linux下挂载(mount)光盘镜像文件、移动硬盘
查看>>
线性链表的c语言实现
查看>>
关于dns服务工作的原理,和配置的细节理解。
查看>>
JavaScript Cookie
查看>>
MVC+Nhibernate+spring.net(三)
查看>>
【图的最短路径】迪杰斯特拉算法求图的最短路径
查看>>
计划人生与程序设计--面对变化
查看>>
JAVA 添加、修改和删除PDF书签
查看>>
How to describe the numerical values?
查看>>
CorelDRAW中如何复制对象属性详解
查看>>
深入理解javascript原型和闭包(9)——简述【执行上下文】下
查看>>