洛谷 [P3623] 免费道路
有 k 条特殊边的生成树
我们发现有一些边是必须的,如果把所有的水泥路都加入并查集,再枚举鹅卵石路,如果这条路能再次加入并查集,说明这条路是必须的
水泥路同样
这样就把必需边求出来了,剩下就可以随意加边了
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 100005;
int init() {
int rv = 0, fh = 1;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') fh = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
rv = (rv<<1) + (rv<<3) + c - '0';
c = getchar();
}
return fh * rv;
}
int n, m, nume, head[MAXN], fa[MAXN], k, cnt, ans[MAXN], ind;
struct edge{
int to, nxt, opt;
}e[MAXN << 1];
void adde(int from, int to, int opt) {
e[++nume].to = to;
e[nume].nxt = head[from];
head[from] = nume;
e[nume].opt = opt;
}
int find(int x) {
if(x != fa[x]) return fa[x] = find(fa[x]);
return fa[x];
}
void merge(int x, int y) {
int r1 = find(x), r2 = find(y);
if(r1 != r2) {
fa[r1] = r2;
}
}
void input() {
for(int i = 1; i <= n; i++) fa[i] = i;
}
bool chk() {
for(int i = 2; i <= n; i++) if(find(i) != find(1)) return 0;
return 1;
}
int main() {
n = init(); m = init(); k = init();
input();
for(int i = 1; i <= m; i++) {
int u = init(), v = init(), opt = init();
adde(u, v, opt); adde(v, u, opt);
if(opt == 1) merge(u, v);
}
for(int i = 1; i <= m * 2; i += 2) {
if(e[i].opt == 0) {
int r1 = find(e[i].to), r2 = find(e[((i - 1) ^ 1) + 1].to);
if(r1 != r2) {
fa[r1] = r2;
ans[++cnt] = i;
ind++;
}
}
}
if(cnt > k || !chk()) {
printf("no solution\n");
return 0;
}
input();
for(int i = 1; i <= nume; i += 2) {
if(e[i].opt == 0) merge(e[i].to, e[((i - 1) ^ 1) + 1].to);
}
for(int i = 1; i <= m * 2; i += 2) {
if(e[i].opt == 1) {
int r1 = find(e[i].to), r2 = find(e[((i - 1) ^ 1) + 1].to);
if(r1 != r2) {
fa[r1] = r2;
ans[++cnt] = i;
}
}
}
if(!chk()) {
printf("no solution\n");
return 0;
}
input();
for(int i = 1; i <= cnt; i++) {
int t = ans[i];
merge(e[t].to, e[((t - 1) ^ 1) + 1].to);
}
for(int i = 1; i <= nume; i += 2) {
if(ind == k) break;
if(e[i].opt == 0) {
int r1 = find(e[i].to), r2 = find(e[((i - 1) ^ 1) + 1].to);
if(r1 != r2) {
fa[r1] = r2;
ans[++cnt] = i;
ind++;
}
}
}
if(ind != k) {
printf("no solution\n");
return 0;
}
for(int i = 1; i <= nume; i += 2) {
if(e[i].opt == 1) {
int r1 = find(e[i].to), r2 = find(e[((i - 1) ^ 1) + 1].to);
if(r1 != r2) {
fa[r1] = r2;
ans[++cnt] = i;
}
}
}
sort(ans + 1, ans + cnt + 1);
for(int i = 1 ; i <= cnt; i++) {
int t = ans[i];
printf("%d %d %d\n", e[((t - 1) ^ 1) + 1].to, e[t].to, e[t].opt);
}
return 0;
}
洛谷 [P3623] 免费道路的更多相关文章
- 洛谷 P5019 铺设道路
题目描述 春春是一名道路工程师,负责铺设一条长度为 \(n\) 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 \(n\) 块首尾相连的区域,一开始,第 \(i\) 块区域下陷的深度 ...
- [NOIP2014] 提高组 洛谷P2296 寻找道路
题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...
- NOIP2014 day2 T2 洛谷P2296 寻找道路
题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...
- 洛谷 P1272 重建道路 解题报告
P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...
- 洛谷 P2505 [HAOI2012]道路 解题报告
P2505 [HAOI2012]道路 题目描述 C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它 ...
- 洛谷P3639 [APIO2013] 道路费用 [生成树的特殊算法]
题目传送门 道路费用 格式难调,题面就不放了. 分析: 这是一道要细(yan)心(jing)的生成树的好(gui)题. 首先我们看到$k$的范围非常小,那么我们就可以直接$2^k$枚举每一条加边是否选 ...
- 洛谷P2296 寻找道路 [拓扑排序,最短路]
题目传送门 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...
- 洛谷——P1907 设计道路
P1907 设计道路 题目描述 Caesar远征高卢回来后,对你大加赞赏,他亲自来到Genoa视察. Genoa在你的建设下变得无比繁荣,由于财政收入的增加,你为城市修建了交通系统.古罗马的交通系统由 ...
- 洛谷P2052 [NOI2011]道路修建(树形DP)
题目描述 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路. 每条道 ...
随机推荐
- python的对数
python的对数 首先要导入 math 模块: import math import numpy as np math.log(8,2),此为以2为底8的对数 等于 math.log2(8); 等于 ...
- list变set去重,set交集
set 取交集 并集 删除没有的元素 不会报错 remove 会报错 https://www.cnblogs.com/alex3714/articles/5717620.html
- 通过rsync+inotify实现数据实时备份
rsync的优点与不足 与传统的cp,scp,tar,备份方式相比,rsync具有安全性高备份迅速支持增量备份的优点,可以满足对实时性要求不高的需求,例如定期备份文件服务器数据到远端服务器,但是,当数 ...
- C++ lambda 表达式 简介
自己根据对lambda表达式的理解,做了一套ppt简单介绍
- Android_组件_Activity基础
一.概述 Activity是应用组件,提供了用户交互的窗口.一个应用由多个彼此联系的Activity组成.它大多数情况是全屏窗口显示,也可以作为悬浮窗口 或者 多窗口模式. 二.生命周期 下图是来自A ...
- h5中的video与audio
·首先带大家熟悉一下video标签的属性方法,根据属性方法做一个小demo, HTML5支持的视频格式: Ogg 带有Theora视频编码+Ogg文件 支持的浏览器:F.O MEPG4 带有H.26 ...
- unix gcc编译过程
gcc编译过程 现代编译器常见的编译过程: 源文件-->预处理-->编译/优化-->汇编-->链接-->可执行文件 对于gcc而言: 第一步 预处理 命令: ...
- 字符编码,ASCII、Unicode与UTF-8的理解
首先我们先要明白的两点是:1.计算机中的信息都是由二进制的0和1储存的:2.我们再计算机屏幕上看到的各种字符都是计算机系统按照一定的规则将二进制数字转换而来的. 一.基本概念. 1.字符集(chars ...
- Kali 远程登陆SSH
一.配置SSH 编辑/etc/ssh/sshd_config 将#PasswordAuthentication no的注释去掉,将NO修改为YES //可以用密码登陆 将PermitRootLogin ...
- TCP/IP网络编程之多线程服务端的实现(一)
为什么引入线程 为了实现服务端并发处理客户端请求,我们介绍了多进程模型.select和epoll,这三种办法各有优缺点.创建(复制)进程的工作本身会给操作系统带来相当沉重的负担.而且,每个进程有独立的 ...