Solution -「COCI 2009-2010」「洛谷 P8076」RESTORAN
\(\mathscr{Description}\)
Link.
给定一个含 \(n\) 个点 \(m\) 条边的简单图, 求一种边二染色方案, 使得所有 \(\deg\ge2\) 的结点都邻接于两种颜色的边.
\(n,m\le10^5\).
\(\mathscr{Solution}\)
清甜味儿的题目比较调剂愚钝的大脑. (
染色, 一开始的思路是匹配或网络流相关, 不过一看数据范围就大概弃了.
第一个 motivation 大概也来自数据范围: 近线性做法 \(\to\) 生成树 (DFS 树) 上构造?
很快, 我们发现树上的 "奇偶染色" (细节见最后一段描述) 是很强大的, 有且仅有树根有可能不合法. 树根在什么情况下合法呢? 简单讨论发现, 我们要求树根在一个偶环里. 可见, 无脑奇偶染色导致了一个挺严的限制因素, 这样的条件显得太奢侈啦!
怎么办呢? 第二个 motivation 是: 保留一条特定的边, 它不在奇偶染色的考虑范围, 仅用于保证树根合法.
保留了一条边, 树根倒是一定合法; 这条边的另一端又称了问题. 什么样的点忽略一条邻接边仍然能在奇偶染色下合法?
其实所有 \(\deg\ge3\) 点都可以.
因此, 我们的算法为: 找到一个 \(\deg\ge3\) 的点 \(u\), 保留其一条邻接边 \((u,v)\), 在连通块剩余边上从 \(v\) 出发 DFS, 树上奇偶染色, 返祖边和对应点子边同色. 染色完成后, 通过 \((u,v)\) 保证 \(v\) 的合法性. 此外需要特殊处理偶环. 当且仅当存在一个连通块为奇环时无解. 复杂度 \(\mathcal O(n+m)\).
\(\mathscr{Code}\)
/*+Rainybunny+*/
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
const int MAXN = 1e5;
int n, m, ecnt = 1, head[MAXN + 5], deg[MAXN + 5], clr[MAXN + 5];
struct Edge { int to, nxt; } graph[MAXN * 2 + 5];
bool vis[MAXN + 5];
inline void link(const int u, const int v) {
graph[++ecnt] = { v, head[u] }, head[u] = ecnt;
graph[++ecnt] = { u, head[v] }, head[v] = ecnt;
}
inline void paint(const int u, const int cur) {
vis[u] = true;
for (int i = head[u], v; i; i = graph[i].nxt) {
if (!clr[i >> 1] && !vis[v = graph[i].to]) {
// printf("%d->%d\n", u, v);
clr[i >> 1] = cur, paint(v, cur ^ 3);
} else if (!clr[i >> 1]) {
clr[i >> 1] = cur;
}
}
}
inline int count(const int u) {
int ret = 1; vis[u] = true;
for (int i = head[u], v; i; i = graph[i].nxt) {
if (!vis[v = graph[i].to]) {
ret += count(v);
}
}
return ret;
}
int main() {
scanf("%d %d", &n, &m);
rep (i, 1, m) {
int u, v; scanf("%d %d", &u, &v);
++deg[u], ++deg[v], link(u, v);
}
rep (u, 1, n) if (!vis[u]) {
if (deg[u] == 1) paint(u, 1);
else if (deg[u] > 2) {
int v = graph[head[u]].to;
clr[head[u] >> 1] = 1, paint(v, 2);
if (!vis[u]) paint(u, 2);
}
}
rep (u, 1, n) if (!vis[u] && deg[u] == 2) {
if (count(u) & 1) return puts("0"), 0;
for (int v = u, las = 0, cur = 1; ;) {
for (int i = head[v], w; i; i = graph[i].nxt) {
if ((w = graph[i].to) != las) {
clr[i >> 1] = cur, cur ^= 3, las = v, v = w;
break;
}
}
if (v == u) break;
}
}
rep (i, 1, m) printf("%d\n", clr[i]);
return 0;
}
Solution -「COCI 2009-2010」「洛谷 P8076」RESTORAN的更多相关文章
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- Solution -「POI 2010」「洛谷 P3511」MOS-Bridges
\(\mathcal{Description}\) Link.(洛谷上这翻译真的一言难尽呐. 给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...
- Solution -「JSOI 2019」「洛谷 P5334」节日庆典
\(\mathscr{Description}\) Link. 给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的). \(|S|\le3\time ...
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- 「洛谷3338」「ZJOI2014」力【FFT】
题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...
- 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】
题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...
- 「洛谷3870」「TJOI2009」开关【线段树】
题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...
- 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】
题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...
随机推荐
- ROS入门21讲(6)
十.ROS中的坐标系管理系统 1.机器人中的坐标变换 某位姿在A.B两个坐标系下的坐标变换 参考:<机器人学导论> 机器人系统中繁杂的坐标系 2.TF功能包 TF功能包能干什么? ①五秒钟 ...
- C++ 简易消息循环
前言 本文将向大家介绍如何使用 C++ 的标准库实现一个异步和并发编程中都非常重要的编程模式:消息循环(Event Loop).尽管市面上存在不少库也提供了同样的功能,但有时候出于一些原因,我们并不想 ...
- python面向对象复习
1.类的语法 # 类的语法 # 定义类 class Dog(object): # 类的属性或者类变量,一般是公共属性,存在类的内存空间,所有实例对象共享 d_type = "京巴" ...
- VictoriaMetrics 中文教程(10)集群版介绍
VictoriaMetrics 中文教程系列文章: VictoriaMetrics 中文教程(01)简介 VictoriaMetrics 中文教程(02)安装 VictoriaMetrics 中文教程 ...
- [python]多线程快速入门
前言 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.由于CPython的GIL限制,多线程实际为单线程,大多只用来处理IO密集型任务. Python一般用标准库 ...
- ubuntu界面文件夹出现了很多隐藏文件夹如何不显示
突然发现文件夹下很多隐藏文件夹都显示出来了,也不知道怎么弄得,想隐藏他们,百度提问无果,提到隐藏这种关键字全是ls这种让我终端查看文件列表. 自己仔细看了看文件夹资源管理器,发现有个按钮 就是这个选项 ...
- Python网络爬虫第一弹
03.Python网络爬虫第一弹<Python网络爬虫相关基础概念> 爬虫介绍 引入 之前在授课过程中,好多同学都问过我这样的一个问题:为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那 ...
- python的egg的制作
egg包是目前最流行的python应用打包部署方式.如何制作和安装egg包?下面我就简单的分析了一下. 总是安装别人的egg包,是不是也想制作自己的egg包呢?好,接下来我们就自己制作一个简单的egg ...
- (Python基础教程之二)在Sublime Editor中配置Python环境
Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...
- Python基础:Python的变量和对象
一.基本原理 Python中一切都是对象,变量中存放的是对象的引用.这是一个普遍的法则.我们举个例子来说,Python是如何来处理的. x = 'blue' y = 'green' z = x 当p ...