洛谷 [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 条双向道路. 每条道 ...
随机推荐
- BZOJ3679: 数字之积(数位dp)
题意 题目链接 Sol 推什么结论啊. 直接大力dp,$f[i][j]$表示第$i$位,乘积为$j$,第二维直接开map 能赢! /* */ #include<iostream> #inc ...
- 2018.10.30 NOIp模拟赛 T1 改造二叉树
[题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论 ...
- mysql的性能优化案例
在一次项目实现中,以前写了个程序,将在txt文件中的电话号码和对应的类型往数据库中插入,小数据量的情况下,用个数组遍历循环的方式,很容易解决,但是当数据量一下 但是,几十万个电话一次性插入,就变得耗时 ...
- javaWeb开发中常见的问题
1.修改表单提交的时候不好使可能是因为没写对应隐藏域的ID 2.el表达式在js代码中要加“”,例如 "${}" 3.JavaScript中的函数也有重载的特性.如果两个input ...
- stark组件前戏(3)之django路由分发的本质include
django路由分发的三种方式 方式一: from django.urls import re_path, include urlpatterns = [ re_path(r'^web/', incl ...
- Python的三种基本数据类型
数字 int(整型) long(长整型),python对长整型没有限制,理论上可以无限大.python3后没有long了. float 字符串 加了引号的都是字符串. 单引号和双引号没有约 ...
- LightOJ 1141 Number Transformation
Number Transformation In this problem, you are given an integer number s. You can transform any inte ...
- Redis实现之复制(二)
PSYNC命令的实现 在Redis实现之复制(一)这一章中,我们介绍了PSYNC命令和它的工作机制,但一直没有说明PSYNC命令的参数以及返回值.现在,我们了解了运行ID.复制偏移量.复制积压缓冲区以 ...
- 洛谷P1540 机器翻译
题目链接:https://www.luogu.org/problemnew/show/P1540
- Java多线程并发技术
Java多线程并发技术 参考文献: http://blog.csdn.net/aboy123/article/details/38307539 http://blog.csdn.net/ghsau/a ...