洛谷 [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虚拟环境 virtualenv工具
为了隔离各类环境,保证环境间不冲突,python中存在虚拟环境,可以在一个文件夹里生成相应的环境,防止与python自带环境冲突 首先我们下载virtualenv,若你未安装python,应到pyth ...
- 四、Shell 数组
Shell 数组 数组中可以存放多个值.Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似). 与大部分编程语言类似,数组元素的下标由0开始. She ...
- 四、MySQL 连接
MySQL 连接 使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库. 实例 以下是从命令行中连接mysql服务器的简单实例: [root@ ...
- 《TensorFlow实战》中AlexNet卷积神经网络的训练中
TensorFlow实战中AlexNet卷积神经网络的训练 01 出错 TypeError: as_default() missing 1 required positional argument: ...
- javascript的基本类型和引用类型
一.基本类型和引用类型 基本的数据类型有5个:undefined,boolean,number,string,null ? 1 2 3 4 5 typeof null; //"object& ...
- Python_装饰器、迭代器、生成器
一.装饰器 装饰器的存在是为了实现开放封闭原则: 封闭: 已实现的功能代码块不应该被修改: 开放: 对现有功能的扩展开放. 理解装饰器的三要素: 函数的作用域 高阶函数 闭包 1. 闭包 闭包定义:如 ...
- JavaScript事件对象与事件的委托
事件对象 包含事件相关的信息,如鼠标.时间.触发的DOM对象等 js默认将事件对象封装好,并自动的以参数的形式,传递给事件处理函数的第1个参数,如下: document.getElementsByTa ...
- 科学计算库Numpy——运算
np.multiply(array1,array2) 该函数用于数组中对应位置上的数相乘. 一维向量 二维数组 np.dot(array1,array2) 两个数组都是一维向量 数组中对应位置上的数相 ...
- 记忆化搜索:HDU1078-FatMouse and Cheese(记忆化搜索)
FatMouse and Cheese Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- vi a.sh ABCD
E: 无法定位软件包 ubuntu预装的是 vim tiny,安装vim full版本,可以解决 卸载vim-tiny: $ sudo apt-get remove vim-common 安装vim ...