CF141E Clearing Up 题解
思路分析
自认为是一道很好的思维题。
直接看上去的想法是:
跑一个生成树,每一次加的边颜色交替进行,直到拉出生成树。
仔细想想,发现可能无法保证最后是一棵树而不是森林,也是说输出都是 \(-1\) 。
然后,我这个弱智就没有任何思路了。
这时,想起“拖帝”的名言:正难则反。于是考虑先筛去不合法的情况。(以下的判断以并查集为基础)
- 当 \(n\) 是偶数时,树边个数是 \(n-1\) 一定是奇数,不可能合法,输出 \(-1\)。
- 我们不管颜色 \(M\) ,把能加入的 \(S\) 色的边加入生成树,记录选入的 \(S\) 色边的条数 \(cnt_1\) 。当 \(cnt_1 < \frac{n-1}{2}\) 时,一定无解。
(因为此时所有的 \(S\) 能加入的都加入了,真实情况只少不多,此时都没到一半,就不可能了。) - 把 \(M\) 色边能加入的加入生成树,并记录 \(cnt_2\) 。如果 \(cnt_1 + cnt_2 < n-1\) 一定无解。
(同样 \(M\) 色的边能加的都加上去了,在所需最少的情况下全部加完都不够,不可能有解。) - 先还原,然后再扫一遍,类似第二步,把 \(S\) 色改成 \(M\) 色即可。(当 \(cnt_2=\frac{n-1}{2}\) 时有解停止。)
思路就是这样,然后直接把 \(S\) 还原即可。
Code
#include <bits/stdc++.h>
#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define quad putchar(' ')
#define Enter putchar('\n')
const int N = 100005;
int n, m, fa[N], tot, cnt1, cnt2, visit[N], ans[N];
struct Node {
int x, y, col;
Node (int _x = 0, int _y = 0, int _col = 0) {x = _x; y = _y; col = _col;}
}node[N];
namespace UFS {
inline void init();
inline int find(int x);
}
using UFS::find;
signed main(void) {
// file("CF141E");
std::cin >> n >> m;
if (n % 2 == 0) {
printf("-1");
return 0;
}
for (int i = 1, x, y; i <= m; i++) {
scanf("%d %d", &x, &y);
char c[4];
scanf("%s", c + 1);
if (c[1] == 'S')
node[++tot] = Node(x, y, 1);
else
node[++tot] = Node(x, y, 2);
}
UFS::init();
for (int i = 1; i <= m; i++) {
int x, y;
if (node[i].col == 2) continue;
x = node[i].x, y = node[i].y;
x = find(x); y = find(y);
if (x == y) continue;
fa[x] = y;
cnt1 ++;
}
if (cnt1 < (n - 1) / 2) {
printf("-1");
return 0;
}
for (int i = 1; i <= m; i++) {
int x, y;
if (node[i].col == 1) continue;
x = node[i].x, y = node[i].y;
x = find(x); y = find(y);
if (x == y) continue;
fa[x] = y; visit[i] = 1;
cnt2 ++;
ans[i] = 1;
}
if (cnt1 + cnt2 < n - 1) {
printf("-1");
return 0;
}
UFS::init();
for (int i = 1; i <= m; i++) {
int x, y;
if (node[i].col == 1) continue;
if (visit[i] == 0) continue;
x = node[i].x, y = node[i].y;
x = find(x); y = find(y);
if (x == y) continue;
fa[x] = y;
}
for (int i = 1; i <= m; i++) {
int x, y;
if (node[i].col == 1) continue;
if (visit[i] == 1) continue;
x = node[i].x, y = node[i].y;
x = find(x); y = find(y);
if (x == y) continue;
fa[x] = y;
cnt2++;
ans[i] = 1;
if (cnt2 == (n - 1) / 2) break;
}
if (cnt2 < (n - 1) / 2) {
printf("-1");
return 0;
}
for (int i = 1; i <= m; i++) {
int x, y;
if (node[i].col == 2) continue;
x = node[i].x, y = node[i].y;
x = find(x); y = find(y);
if (x == y) continue;
fa[x] = y;
ans[i] = 1;
}
printf("%d\n", n - 1);
for (int i = 1; i <= m; i++)
if (ans[i]) printf("%d ", i);
}
namespace UFS {
inline void init() {
for (int i = 1; i <= n; i++)
fa[i] = i;
}
inline int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
}
CF141E Clearing Up 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- zookeeper篇-watch命令
点赞再看,养成习惯,微信搜索「小大白日志」关注这个搬砖人. 文章不定期同步公众号,还有各种一线大厂面试原题.我的学习系列笔记. 每个路径节点都有一个watcher监控,当该节点数据改变时(CRUD), ...
- 安装黑苹果 、 Mac OS虚拟机
Mac OS 虚拟机 所需文件地址 unlocker 为VMware 新增Apple Mac OS X操作系统 Install_macOS_Monterey_12.0.1_21A559.iso 提取码 ...
- netty系列之:netty中的核心解码器json
目录 简介 java中对json的支持 netty对json的解码 总结 简介 程序和程序之间的数据传输方式有很多,可以通过二进制协议来传输,比较流行的像是thrift协议或者google的proto ...
- FreeRTOS --(9)任务管理之启动调度器
转载自 https://blog.csdn.net/zhoutaopower/article/details/107057528 在使用 FreeRTOS 的时候,一般的,先创建若干任务,但此刻任务并 ...
- 用户与安全 -(1)Linux用户及组管理
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 前言 Linux 是多用户多任务操作系统,换句话说,Linux 系统支持多个用户在同一时间内登 ...
- 实现Linux系统的回收站
Linux系统默认没有回收站功能,使用rm命令进行删除操作,文件就会直接从系统中删除,很难恢复. 今天我们利用简单的shell脚本实现Linux系统下的回收站机制. 先提供脚本代码 [root@qll ...
- APP应用前端开发
1.开发手机APP前端要重视meta标签的编写: 2.注意HTML5标签在前端开发中的使用: 3.前端制作要舍弃CSS float属性(可flex布局),用绝对定位不利于页面布局的扩展: 4.APP前 ...
- WPF 制作雷达扫描图
实现一个雷达扫描图. 源代码在TK_King/雷达 (gitee.com),自行下载就好了 制作思路 绘制圆形(或者称之轮) 绘制分割线 绘制扫描范围 添加扫描点 具体实现 首先我们使用自定义的控件. ...
- 程序包 applets.user.service.UserService 不存在-2022新项目
一.问题由来 接上一篇文章使用maven进行打包时报中文乱码错误,经过多次尝试后最终解决问题,显示出真正的错误信息如下: 程序包 applets.user.service.UserService 不存 ...
- K8S 使用Minikube搭建Kubernetes(K8S)~单机运行Kubernetes~适用于快速学习
在一台主机上运行起来的Kubernetes,仅适用于学习!~~~ 系统版本:CentOS Linux release 7.6.1810 (Core) 软件版本:Docker-ce-18.06.0.Ku ...