BZOJ3624:[APIO2008]免费道路
浅谈并查集: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]免费道路的更多相关文章
- [BZOJ3624][Apio2008]免费道路
[BZOJ3624][Apio2008]免费道路 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入”. 题解 第一步,先尽量加入 c = 1 的边,若未形成一个连通块,则得到必须加入 ...
- BZOJ3624: [Apio2008]免费道路(最小生成树)
题意 题目链接 Sol 首先答案一定是一棵树 这棵树上有一些0边是必须要选的,我们先把他们找出来,如果数量$\geqslant k$显然无解 再考虑继续往里面加0的边,判断能否加到k条即可 具体做法是 ...
- bzoj 3624: [Apio2008]免费道路 生成树的构造
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 111 Solved: 4 ...
- 题解 Luogu P3623 [APIO2008]免费道路
[APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可 ...
- BZOJ 3624: [Apio2008]免费道路
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1201 Solved: ...
- [Apio2008]免费道路[Kruscal]
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1292 Solved: ...
- P3623 [APIO2008]免费道路
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special Judge Submit: 2143 Solved: 88 ...
- Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路
首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...
- [APIO2008]免费道路
[APIO2008]免费道路 BZOJ luogu 先把必须连的鹅卵石路连上,大于k条no solution 什么样的鹅卵石路(u,v)必须连?所有水泥路都连上仍然不能使u,v连通的必须连 补全到k条 ...
- [APIO2008]免费道路(生成树)
新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可能保持所有道路免费.为此亟待制定一个新的 ...
随机推荐
- flask实现模仿知乎
上个月花了一个月的时间学习flask框架实现了一个简陋的知乎,有提问,回答,写文章,个人信息页,个人信息修改等功能,因刚接触学习flask,后端代码实现很多冗余,依旧需要修改. github: htt ...
- rsh命令配置于使用
安装环境:一台centos6.10虚拟机,一台centos7.5虚拟机,全部使用root用户登录. 两台机器上都要安装rsh.rsh-server.xinetd包. 两台机器都要关闭防火墙并配置/et ...
- Shell编程之循环控制及状态返回值
1.break.continue.exit.return的对比 break.continue在条件语句和循环语句中用于控制程序走向: exit用于终止所有语句并退出当前脚本,还可以返回上一次程序或命令 ...
- poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】
题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Sub ...
- 音乐下载api
青檬音乐 http://tingapi.ting.baidu.com/v1/restserver/ting?from=android&version=5.6.5.6&format=js ...
- JavaScript实现的功能
1.js事件阻止冒泡的应用 1)问题描述: 单机除了这两个元素,触发事件,: 可用阻止事件冒泡 2)解决方法: $('body').click(function(e){ $('#searchTree' ...
- 用java.lang.Math.random()语句,随机输出{size:自定义参数}个数不重复并且按顺序从小到大排列(冒泡排序)
package com.test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lan ...
- iBatis.net 第一篇 搭建
iBatis.net 和 iBatis 是有区别的,一个是在net下使用的,另一个是在java下使用. 要想使用,需要下载相关iBatis.net包 1.下载iBatis.net,在网上有很多下载cs ...
- QT 布局时使用 addStretch 可伸缩设置
今天在使用addStretch,布局的时候,发现addStretch竟然是可以平均分配的,有意思.比如: QVBoxLayout *buttonLayout = new QVBoxLayout; bu ...
- hdoj1006--Tick and Tick
Problem Description The three hands of the clock are rotating every second and meeting each other ma ...