有 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] 免费道路的更多相关文章

  1. 洛谷 P5019 铺设道路

    题目描述 春春是一名道路工程师,负责铺设一条长度为 \(n\) 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 \(n\) 块首尾相连的区域,一开始,第 \(i\) 块区域下陷的深度 ...

  2. [NOIP2014] 提高组 洛谷P2296 寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  3. NOIP2014 day2 T2 洛谷P2296 寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  4. 洛谷 P1272 重建道路 解题报告

    P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...

  5. 洛谷 P2505 [HAOI2012]道路 解题报告

    P2505 [HAOI2012]道路 题目描述 C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它 ...

  6. 洛谷P3639 [APIO2013] 道路费用 [生成树的特殊算法]

    题目传送门 道路费用 格式难调,题面就不放了. 分析: 这是一道要细(yan)心(jing)的生成树的好(gui)题. 首先我们看到$k$的范围非常小,那么我们就可以直接$2^k$枚举每一条加边是否选 ...

  7. 洛谷P2296 寻找道路 [拓扑排序,最短路]

    题目传送门 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...

  8. 洛谷——P1907 设计道路

    P1907 设计道路 题目描述 Caesar远征高卢回来后,对你大加赞赏,他亲自来到Genoa视察. Genoa在你的建设下变得无比繁荣,由于财政收入的增加,你为城市修建了交通系统.古罗马的交通系统由 ...

  9. 洛谷P2052 [NOI2011]道路修建(树形DP)

    题目描述 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路. 每条道 ...

随机推荐

  1. iOS中View的创建过程

    ios应用中控制器view的创建方式有三种:storyboard.xib和代码,当APP启动后View的具体加载过程如图(苹果官方): 假设我使用的是WYSViewController控制器 应用启动 ...

  2. TCP/IP与OSI参考模型原理

    网络是很重要同时也是很难理解的知识,这篇文章将会用自己容易理解的方式来记录有关网络的tcp与osi模型内容,不求专业深刻,但求通俗易懂也好. OSI参考模型 OSI定义了网络互连的七层框架(物理层.数 ...

  3. 【JAVA】JVM常用工具

    JDK内置工具使用 jps(Java Virtual Machine Process Status Tool)    查看所有的jvm进程,包括进程ID,进程启动的路径等等. jstack(Java ...

  4. PHP PDO 使用类

    PDO类 <?php class MYPDO { protected static $_instance = null; protected $dbName = ''; protected $d ...

  5. 科学计算库Numpy——数组生成

    等差数组 使用np.arange()或np.linspace()生成元素是等差数列的数组. 以10为底的数组 使用np.logspace()生成元素是以10为底的数组. 数组扩展 使用np.meshg ...

  6. POJ:2185-Milking Grid(KMP找矩阵循环节)

    Milking Grid Time Limit: 3000MS Memory Limit: 65536K Description Every morning when they are milked, ...

  7. 初识java,编写hello world语句

    JDK: Java Develpment Kit - java开发工具包 JRE: Java Runtime Environment - java运行环境 JVM: Java Virtual Mach ...

  8. [转]Git for windows 下vim解决中文乱码的有关问题

    Git for windows 下vim解决中文乱码的问题 原文链接:Git for windows 下vim解决中文乱码的有关问题 1.右键打开Git bash: 2.cd ~ 3.vim .vim ...

  9. 谈一谈Tomcat中webSocket,Jetty WebSocket 和Spring WebSocket以及github中Java-WebSocket.jar分别对Socket协议的角色定位以及效果的不同点;

    开局先上一张图:(http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html)   当前截图来自于apache的tomcat官网(问:为 ...

  10. cf965e Short Code

    ref #include <algorithm> #include <iostream> #include <cstring> #include <cstdi ...