题意:

一张图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]免费道路 [生成树 并查集]的更多相关文章

  1. BZOJ 3624 [Apio2008]免费道路:并查集 + 生成树 + 贪心【恰有k条特殊路径】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3624 题意: 给你一个无向图,n个点,m条边. 有两种边,种类分别用0和1表示. 让你求一 ...

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

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

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

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

  4. bzoj 3624: [Apio2008]免费道路【生成树+贪心】

    先把水泥路建生成树,然后加鹅卵石路,这里加的鹅卵石路是一定要用的(连接各个联通块),然后初始化并查集,先把必需的鹅卵石路加进去,然后随便加鹅卵石路直到k条,然后加水泥路即可. 注意判断无解 #incl ...

  5. 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 这 ...

  6. BZOJ.3624.[APIO2008]免费道路(Kruskal)

    题目链接 我们发现有些白边是必须加的,有些是多余的. 那么我们先把所有黑边加进去,然后把必须要加的白边找出来. 然后Kruskal,把必须要加的白边先加进去,小于K的话再加能加的白边.然后加黑边. 要 ...

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

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

  8. 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 ...

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

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

随机推荐

  1. Oil Deposits(dfs水)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1241 Oil Deposits Time Limit: 2000/1000 MS (Java/Othe ...

  2. Spring框架学习笔记(4)——配置bean more

    1.配置List属性 <!-- 配置List属性 --> <bean id="person4" class="com.broadtext.beans.c ...

  3. [国嵌攻略][117][LED驱动程序设计]

    LED程序设计 1.编写内核模块 2.搭建字符驱动框架 3.实现设备方法 头文件 <linux/io.h> writel() 1.编译/安装驱动 make cp leddev.ko ... ...

  4. [国嵌攻略][060][LCD工作原理解析]

    LCD硬件体系 1.LCD液晶屏 液晶属于一种有机化合物,分子形状为长棒状,在不同的电流作用下,分子会有规律旋转,这样对光线产生一定的控制形成一个像素,而很多像素右可以构成完整的图像. LCD是Liq ...

  5. ReentrantLock与Condition构造有界缓存队列与数据栈

    通过ReentrantLock与Condition的设计,以数组为基础,可以实现简单的队列和栈的数据结构,临界阻塞的效果. ReentrantLock相对于synchronized比较大的一个区别是有 ...

  6. Web API (四) 特性路由(Attribute Route)

    特性路由 是Web API 2 中提出的一种新的类型的路由,正如其名称那样,它是通过特性(Attribute) 来定义路由的,相比之前的基于模式(Convertion Based)的路由,特性路由 能 ...

  7. 百万级别QPS轻量级PHP框架Steeze介绍

    系统简介   Steeze是一个优雅.简洁而又高效的PHP开源框架,在整合了知名框架ThinkPHP和Laravel优点的同时,重写了底层架构,增强了功能实现. 支持swoole模型运行,支持容器.模 ...

  8. 【开发技术】视频URL采集

    http://www.joyplus.tv/joypluscms   志精

  9. -------- Rootkit 核心技术——利用 nt!_MDL 突破 KiServiceTable 的只读访问限制 Part II --------

    ------------------------------------------------------------------------------------------- 本篇开始进入正题 ...

  10. android之间传递list

    Intent intent = new Intent(getActivity(), Activity_Character.class); intent.putExtra("mlTrait&q ...