浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3624

题目要求的就是恰好包含\(k\)条鹅卵石路的生成树。

首先我们用水泥边建出生成树森林,然后再用鹅卵石边把森林连成一棵树。

如果需要用到的鹅卵石边大于\(k\)则无解。

如果无法连成一棵树则无解。

连成一棵树之后也许此时用到的鹅卵石边比\(k\)要小,我们暂且称已经用到的鹅卵石边为必要边。

我们把树全部拆掉,然后把必要边连上,在看看能不能把不足的\(k\)条鹅卵石边补上,补得上就有解,否则无解。

剩下的用水泥边填上即可。

时间复杂度:\(O(nlogn)\)

空间复杂度:\(O(n+m)\)

代码如下:

#include <cstdio>
using namespace std; const int maxn=2e4+5,maxm=1e5+5; int fa[maxn];bool bo[maxm];
int n,m,k,cnt1,cnt2,cnt,tot; int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
} struct road {
int a,b; road() {} road(int _a,int _b) {
a=_a,b=_b;
}
}cob[maxm],cem[maxm],ans[maxn]; int find(int x) {
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
} int main() {
tot=n=read(),m=read(),k=read();
for(int i=1;i<=m;i++) {
int a=read(),b=read(),opt=read();
if(opt)cem[++cnt1]=road(a,b);
else cob[++cnt2]=road(a,b);
}
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=cnt1;i++) {
int p=find(cem[i].a),q=find(cem[i].b);
if(p==q)continue;
fa[p]=q,tot--;
}
if(tot-1>k) {puts("no solution");return 0;}
for(int i=1;i<=cnt2;i++) {
int p=find(cob[i].a),q=find(cob[i].b);
if(p==q)continue;
fa[p]=q,tot--,bo[i]=1;
}
if(tot!=1) {puts("no solution");return 0;}
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=cnt2;i++)
if(bo[i]) {
ans[++cnt]=cob[i];
int p=find(cob[i].a),q=find(cob[i].b);
fa[p]=q;k--;
}
for(int i=1;i<=cnt2&&k;i++)
if(!bo[i]) {
int p=find(cob[i].a),q=find(cob[i].b);
if(p==q)continue;
fa[p]=q,k--;ans[++cnt]=cob[i];
}
if(k) {puts("no solution");return 0;}
for(int i=1;i<=cnt;i++)
printf("%d %d 0\n",ans[i].a,ans[i].b);
for(int i=1;i<=cnt1;i++) {
int p=find(cem[i].a),q=find(cem[i].b);
if(p==q)continue;
printf("%d %d 1\n",cem[i].a,cem[i].b);
fa[p]=q;
}
return 0;
}

BZOJ3624:[APIO2008]免费道路的更多相关文章

  1. [BZOJ3624][Apio2008]免费道路

    [BZOJ3624][Apio2008]免费道路 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入”. 题解 第一步,先尽量加入 c = 1 的边,若未形成一个连通块,则得到必须加入 ...

  2. BZOJ3624: [Apio2008]免费道路(最小生成树)

    题意 题目链接 Sol 首先答案一定是一棵树 这棵树上有一些0边是必须要选的,我们先把他们找出来,如果数量$\geqslant k$显然无解 再考虑继续往里面加0的边,判断能否加到k条即可 具体做法是 ...

  3. bzoj 3624: [Apio2008]免费道路 生成树的构造

    3624: [Apio2008]免费道路 Time Limit: 2 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 111  Solved: 4 ...

  4. 题解 Luogu P3623 [APIO2008]免费道路

    [APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可 ...

  5. BZOJ 3624: [Apio2008]免费道路

    3624: [Apio2008]免费道路 Time Limit: 2 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1201  Solved:  ...

  6. [Apio2008]免费道路[Kruscal]

    3624: [Apio2008]免费道路 Time Limit: 2 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1292  Solved:  ...

  7. P3623 [APIO2008]免费道路

    3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special Judge Submit: 2143 Solved: 88 ...

  8. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  9. [APIO2008]免费道路

    [APIO2008]免费道路 BZOJ luogu 先把必须连的鹅卵石路连上,大于k条no solution 什么样的鹅卵石路(u,v)必须连?所有水泥路都连上仍然不能使u,v连通的必须连 补全到k条 ...

  10. [APIO2008]免费道路(生成树)

    新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可能保持所有道路免费.为此亟待制定一个新的 ...

随机推荐

  1. Linux软件包管理 RMP包管理

    概述 RPM 包的命名一般都会遵守统一的命名规则,例如: httpd-2.2.15-15.el6.centos.1.i686.rpm 其中的各项代表的含义如下: httpd:软件包名. 2.2.15: ...

  2. 【Flask】Sqlalchemy lazy

    ### 懒加载:在一对多,或者多对多的时候,如果想要获取多的这一部分的数据的时候,往往能通过一个属性就可以全部获取了.比如有一个作者,想要或者这个作者的所有文章,那么可以通过user.articles ...

  3. 继承Thread类与实现Runnable接口

    java中创建线程有两种方式: 1. 类继承Thread类,重写run方法,每创建一个实例对象即开启一个线程 2. 类实现Runnable接口,重写run方法,将实例对象传入新建Thread的方法: ...

  4. 2018.7.12训练赛 -K

    水题 判断素数 因为范围是到16位,所以可以用long long存储 然后判断是否为素数就ok了. 但我提交之后显示10个测试样例通过了9个.......原因是下面标红的部分. 埃氏筛法:若a是合数, ...

  5. 优美的英文诗歌Beautiful English Poetry

    <When you are old>——<当你老了> --- William Butler Yeats ——威廉·巴特勒·叶芝When you are old and grey ...

  6. Deep Learning概述

    1.深度学习发展简史 2.三步实现深度学习 2.1Neural Network 神经网络由模仿脑部神经系统发展而来,一个节点称为一个“Neuron”,包括连接在节点上面的weights和biases. ...

  7. servlet原理分析

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  8. WebUploader API文档

    Web Uploader内部类的详细说明,以下提及的功能类,都可以在WebUploader这个变量中访问到. As you know, Web Uploader的每个文件都是用过AMD规范中的defi ...

  9. HTML中table边框的显示总结

    一.1.显示表格的4个边框:<table border frame=box>2.只显示上边框: <table border frame=above>3.只显示下边框: < ...

  10. linux系统内SAMBA共享问题

    最近将项目迁移到了公司服务器上,以后客户端调试和服务端开发都要去链接这台服务器,但是开发就需要调试,也需要log信息,同一局域网内,如何链接服务器并随时查看服务器上的log信息呢? 今天搞了一下,把步 ...