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 & ...
随机推荐
- transition 动画过渡
1. html 结构 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- Go 语言 结构体和方法
@ 目录 1. 结构体别名定义 2. 工厂模式 3. Tag 原信息 4. 匿名字段 5. 方法 1. 结构体别名定义 变量别名定义 package main import "fmt&quo ...
- linux 下通过fork实现后台运行进程
1 # 通常建议使用双fork方法.在每个fork处,父级退出,子级继续 2 3 #!/usr/bin/env python 4 5 import time,platform 6 7 import o ...
- Springmvc01-什么是Springmvc
首先,我们回顾一下什么是MVC 1.什么是MVC MVC是模型(model),视图(View),控制器(Controller)的简写,是一种软件基本规范 Model(模型):数据模型,提供要展示的 ...
- WorkCount
此项目码云链接 软件测试方法和技术第二次作业 1 作业内容 根据WordCount的需求描述,先编程实现,再编写单元测试,最后撰写博客.至少完成需求中的基本功能. 2 WordCount需求说明 Wo ...
- [AcWing 35] 反转链表
迭代版本 点击查看代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next ...
- 论文解读(Graphormer)《Do Transformers Really Perform Bad for Graph Representation?》
论文信息 论文标题:Do Transformers Really Perform Bad for Graph Representation?论文作者:Chengxuan Ying, Tianle Ca ...
- 五三想休息,今天还学习,图解二叉树的层序遍历BFS(广度优先)模板,附面试题题解
壹 ❀ 引 我在从JS执行栈角度图解递归以及二叉树的前.中.后遍历的底层差异一文中,从一个最基本的数组遍历引出递归,在掌握递归的书写规则后,又从JS执行栈角度解释了二叉树三种深度优先(前序.中序后序) ...
- BootstrapBlazor实战 Markdown 编辑器使用
基础工程使用工程: B08. BootstrapBlazor实战 Menu 导航菜单使用 实战BootstrapBlazorMenu Markdown 编辑器使用, 以及整合Freesql orm快速 ...
- 做SaaS的程序员们,是时候关注企业架构了
SaaS赛道是一个超大赛道,足够容纳上万家服务商,不太可能有哪个服务商能满足所有场景,大部分SaaS服务商在某个垂直领域,提供差异化的产品和服务.SaaS产品大部分都是面向B端客户,少部分面向C端客户 ...