BZOJ 3624: [Apio2008]免费道路 [生成树 并查集]
题意:
一张图0,1两种边,构造一个恰有k条0边的生成树
优先选择1边构造生成树,看看0边是否小于k
然后保留这些0边,补齐k条,再加1边一定能构成生成树
类似kruskal的证明
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2e4+, M=1e5+;
typedef long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} int n, m, k, u, v, c, m0, m1, p;
struct meow{int u, v, c;}a[M], b[M], ans[N];
int fa[N];
int find(int x) {return x==fa[x] ? x : fa[x]=find(fa[x]);}
int flag[N];
int main() {
freopen("in","r",stdin);
n=read(); m=read(); k=read();
for(int i=; i<=m; i++) {
u=read(), v=read(), c=read();
if(c==) a[++m1]=(meow){u,v,c};
else b[++m0]=(meow){u,v,c};
} int cnt=;
for(int i=; i<=n; i++) fa[i]=i;
for(int i=; i<=m1; i++) {
u=a[i].u, v=a[i].v;
int x=find(u), y=find(v);
if(x==y) continue;
fa[x]=y;
if(++cnt == n-) break;
}
for(int i=; i<=m0; i++) {
u=b[i].u, v=b[i].v;
int x=find(u), y=find(v);
if(x==y) continue;
fa[x]=y; ans[++p]=b[i]; flag[i]=;
if(++cnt == n-) break;
}
if(p > k || cnt < n-) {puts("no solution"); return ;} for(int i=; i<=n; i++) fa[i]=i;
for(int i=; i<=p; i++) fa[find(ans[i].u)] = find(ans[i].v);
cnt=p;
if(cnt<k) for(int i=; i<=m0; i++) if(!flag[i]){
u=b[i].u, v=b[i].v;
int x=find(u), y=find(v);
if(x==y) continue;
fa[x]=y; ans[++cnt]=b[i];
if(cnt == k) break;
}
for(int i=; i<=m1; i++) {
u=a[i].u, v=a[i].v;
int x=find(u), y=find(v);
if(x==y) continue;
fa[x]=y; ans[++cnt]=a[i];
if(cnt == n-) break;
}
for(int i=; i<=cnt; i++) printf("%d %d %d\n",ans[i].u, ans[i].v, ans[i].c);
}
2017-10-03 今天又写了一下 以前好像有点问题洛谷wa1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 1e5+, M = 1e5+;
typedef long long ll;
inline int read() {
char c=getchar(); int x=,f=;
while(c<''||c>'') {if(c=='-')f=-;c=getchar();}
while(c>=''&&c<='') {x=x*+c-'';c=getchar();}
return x*f;
} int n, m, k;
struct edge {int u, v, c;} e[M];
int flag[N], fa[N], ans[N];
int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
int main() {
//freopen("in", "r", stdin);
scanf("%d %d %d", &n, &m, &k);
for(int i=; i<=m; i++) e[i].u = read(), e[i].v = read(), e[i].c = read(); for(int i=; i<=n; i++) fa[i] = i;
int num = ;
for(int i=; i<=m; i++) if(e[i].c == ) {
int f1 = find(e[i].u), f2 = find(e[i].v);
if(f1 == f2) continue;
fa[f1] = f2;
if(++num == n-) break;
}
int one = ;
for(int i=; i<=m; i++) if(e[i].c == ) {
int f1 = find(e[i].u), f2 = find(e[i].v);
if(f1 == f2) continue;
fa[f1] = f2;
one++; ans[++ans[]] = i; flag[i] = ;
if(++num == n-) break;
}
if(one > n-k) {puts("no solution"); return ;}
if(num < n-) {puts("no solution"); return ;} for(int i=; i<=n; i++) fa[i] = i;
num = ;
for(int i=; i<=m; i++) if(e[i].c == ) {
int f1 = find(e[i].u), f2 = find(e[i].v);
if(f1 == f2) continue;
fa[f1] = f2;
if(++num == n-) break;
}
int zero = ;
for(int i=; i<=m; i++) if(e[i].c == ) {
int f1 = find(e[i].u), f2 = find(e[i].v);
if(f1 == f2) continue;
fa[f1] = f2;
zero++; ans[++ans[]] = i; flag[i] = ;
if(++num == n-) break;
}
if(zero > k) {puts("no solution"); return ;} for(int i=; i<=n; i++) fa[i] = i;
num = ans[];
for(int i=, t; i<=ans[]; i++) t = ans[i], fa[find(e[t].u)] = find(e[t].v);
if(zero < k) for(int i=; i<=m; i++) if(!flag[i] && e[i].c == ) {
int f1 = find(e[i].u), f2 = find(e[i].v);
if(f1 == f2) continue;
fa[f1] = f2;
ans[++ans[]] = i;
++num;
if(++zero == k) break;
}
if(num < n-) for(int i=; i<=m; i++) if(!flag[i] && e[i].c == ) {
int f1 = find(e[i].u), f2 = find(e[i].v);
if(f1 == f2) continue;
fa[f1] = f2;
ans[++ans[]] = i;
if(++num == n-) break;
} if(zero != k || num != n-) {puts("no solution"); return ;}
for(int i=, t; i<=ans[]; i++) t = ans[i], printf("%d %d %d\n", e[t].u, e[t].v, e[t].c);
}
BZOJ 3624: [Apio2008]免费道路 [生成树 并查集]的更多相关文章
- BZOJ 3624 [Apio2008]免费道路:并查集 + 生成树 + 贪心【恰有k条特殊路径】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3624 题意: 给你一个无向图,n个点,m条边. 有两种边,种类分别用0和1表示. 让你求一 ...
- bzoj 3624: [Apio2008]免费道路 生成树的构造
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 111 Solved: 4 ...
- BZOJ 3624: [Apio2008]免费道路
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1201 Solved: ...
- bzoj 3624: [Apio2008]免费道路【生成树+贪心】
先把水泥路建生成树,然后加鹅卵石路,这里加的鹅卵石路是一定要用的(连接各个联通块),然后初始化并查集,先把必需的鹅卵石路加进去,然后随便加鹅卵石路直到k条,然后加水泥路即可. 注意判断无解 #incl ...
- Bzoj 3624: [Apio2008]免费道路 (贪心+生成树)
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 这 ...
- BZOJ.3624.[APIO2008]免费道路(Kruskal)
题目链接 我们发现有些白边是必须加的,有些是多余的. 那么我们先把所有黑边加进去,然后把必须要加的白边找出来. 然后Kruskal,把必须要加的白边先加进去,小于K的话再加能加的白边.然后加黑边. 要 ...
- [APIO2008]免费道路(生成树)
新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可能保持所有道路免费.为此亟待制定一个新的 ...
- 3624: [Apio2008]免费道路
Description Input Output 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 ...
- [Apio2008]免费道路[Kruscal]
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1292 Solved: ...
随机推荐
- 大区间素数筛选(POJ 2689)
/* *POJ 2689 Prime Distance *给出一个区间[L,U],找出区间内容.相邻的距离最近的两个素数和距离最远的两个素数 *1<=L<U<=2147483647 ...
- linux基本命令学习02
=============================================================================a.txtc:\abc\a.txt windo ...
- Qt 共享库(动态链接库)和静态链接库的创建及调用
前言: 编译器 Qt Creator, 系统环境 win7 64 位 1.创建共享库: 新建文件或项目->选择 Library 和 c++ 库->选择共享库->下一步(工程名为 sh ...
- DevGridControl中GridView排序问题
在对表格数据源为字符串类型的列排序时,为了实现按照值大小进行排序,需要进行以下处理: 先设置该列SortMode属性为自定义属性 gridColumn1.SortMode = DevExpress.X ...
- JSP内置对象1(request,response,session)
request对象 response对象:请求重定向与请求转发的区别. session对象:表示客户端与服务器的一次会话,也就是用户浏览网站所花费的时间.在服务器的内存中保存着不同用户的session ...
- 那些年~~~我们的C#笔试内测题目
<深入.NET平台和C#编程>内部测试题-笔试试卷 一 选择题 1) 以下关于序列化和反序列化的描述错误的是( C). a) 序列化是将对象的状态存储到特定存储介质中的过程 b) 二进制格 ...
- C#编写影院售票系统(A project with a higher amount of gold )(2:相关代码)
此篇文章为项目代码,,,需要项目需求 ,思路分析与窗体效果请访问:http://www.cnblogs.com/lsy131479/p/8367304.html 项目类图: 影院类: using Sy ...
- php 利用Gd库添加文字水印乱码的问题及解决方案
最近一个项目进行了服务器迁移,部署后发现 ,其中一个为图片添加水印文字的功能出现了乱码问题,确认功能代码不存在问题,同时项目代码都是使用UTF-8编码,不存在编码问题,也检查排除了字体文件出现问题的可 ...
- 译-Web Service剖析: XML, SOAP 和WSDL 用于独立于平台的数据交换
本文是翻译内容,原文参见: Anatomy of a Web Service: XML, SOAP and WSDL for Platform-independent Data Exchange We ...
- 转-python中的闭包
出处:http://www.cnblogs.com/ma6174/archive/2013/04/15/3022548.html 记录下 简单说,闭包就是根据不同的配置信息得到不同的结果 再来看看专业 ...