CF547D Mike and Fish
欧拉回路,巧妙的解法。
发现每一个点$(x, y)$实际上是把横坐标和$x$和纵坐标$y$连一条线,然后代进去跑欧拉回路,这样里一条边对应了一个点,我们只要按照欧拉回路间隔染色即可。
注意到原图可能并不是一个完全的欧拉图,但是度数为奇数的点只可能有偶数个,我们可以在连完边之后再把度数为奇数的点两两配对连边,这样子就是一个完全的欧拉图了。
然后……这个图仍然可能不连通,所以每一个点都代进去搜一下。
思考一下这样子为什么是对的,我们从一个点开始走,如果这个点染了一个颜色,那么这个点同一行或者是同一列的点都不要再染同一个颜色了,向别的地方走的意思就是不染相同的颜色,这样子看似贪心地染一定能求出所需要地答案,欧拉回路其实就是确定了一个染色的顺序,我们只要看一看走了正反哪一条边就可以确定染色了。
时间复杂度应当是$O(n)$的,但是我还写了个离散化……
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = 2e5 + ;
const int inf = << ; int n, totx, toty, tot = , head[N << ];
int deg[N << ], ax[N], ay[N], col[N];
bool vis[N << ]; struct Edge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} struct Innum {
int val, id; friend bool operator < (const Innum &x, const Innum &y) {
if(x.val != y.val) return x.val < y.val;
else return x.id < y.id;
} } in[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} inline void discrete(int *arr, int preLen, int &nowLen) {
in[].val = -inf;
for(int i = ; i <= preLen; i++)
in[i].val = arr[i], in[i].id = i;
sort(in + , in + + preLen);
nowLen = ;
for(int i = ; i <= preLen; i++) {
if(in[i].val != in[i - ].val) ++nowLen;
arr[in[i].id] = nowLen;
}
} void dfs(int x) {
for(int &i = head[x]; i; i = e[i].nxt) {
int y = e[i].to, t = i;
if(vis[t] || vis[t ^ ]) continue;
vis[t] = ;
dfs(y);
}
} int main() {
read(n);
for(int i = ; i <= n; i++)
read(ax[i]), read(ay[i]); /* printf("%d\n", n);
for(int i = 1; i <= n; i++)
printf("%d %d\n", ax[i], ay[i]); */ discrete(ax, n, totx), discrete(ay, n, toty);
for(int i = ; i <= n; i++) {
add(ax[i], ay[i] + totx), add(ay[i] + totx, ax[i]);
++deg[ax[i]], ++deg[ay[i] + totx];
} int lst = ;
for(int i = ; i <= totx + toty; i++) {
if(!(deg[i] & )) continue;
if(!lst) lst = i;
else add(lst, i), add(i, lst), ++deg[i], ++deg[lst], lst = ;
} for(int i = ; i <= totx + toty; i++)
if(deg[i]) dfs(i); for(int i = ; i <= n; i++)
putchar(vis[i << ] ? 'r' : 'b'); printf("\n");
return ;
}
CF547D Mike and Fish的更多相关文章
- CF547D Mike and Fish 建图
题意: 有点长→CF547DMike and Fish. 分析: 其实也没什么好分析的,我这也是看的题解. (不过,那篇题解好像文字的代码不太对劲) 这里直接说做法,正确性自证: 对输入的,将横.纵坐 ...
- cf547D. Mike and Fish(欧拉回路)
题意 题目链接 Sol 说实话这题我到现在都不知道咋A的. 考试的时候是对任意相邻点之间连边,然后一分没有 然后改成每两个之间连一条边就A了.. 按说是可以过掉任意坐标上的点都是偶数的数据啊.. #i ...
- 「CF547D」 Mike and Fish
「CF547D」 Mike and Fish 传送门 介绍三种做法. \(\texttt{Solution 1}\) 上下界网络流 我们将每一行.每一列看成一个点. 两种颜色的数量最多相差 \(1\) ...
- Codeforces 247D Mike and Fish
Mike and Fish 我们可以把这个模型转换一下就变成有两类点,一类是X轴, 一类是Y轴, 每个点相当于对应的点之间建一条边, 如果这条边变红两点同时+1, 变蓝两点同时-1. 我们能发现这个图 ...
- CF 547 D. Mike and Fish
D. Mike and Fish http://codeforces.com/contest/547/problem/D 题意: 给定平面上n个点,将这些点染成红或者蓝色,要求每行.每列红色点与蓝色点 ...
- CodeForces - 547D: Mike and Fish (转化为欧拉回路)(优化dfs稠密图)(定向问题)
As everyone knows, bears love fish. But Mike is a strange bear; He hates fish! The even more strange ...
- codeforces #305 D Mike and Fish
正解貌似是大暴搜? 首先我们考虑这是一个二分图,建立网络流模型后很容易得出一个算法 S->行 容量为Num[X]/2; 行->列 容量为1 且要求(x,y)这个点存在 列->T 容量 ...
- Codeforces 547D Mike and Fish
Description 题面 题目大意:有一个的网格图,给出其中的 \(n\) 个点,要你给这些点染蓝色或红色,满足对于每一行每一列都有红蓝数量的绝对值之差不超过1 Solution 首先建立二分图, ...
- Codeforces.547D.Mike and Fish(思路 欧拉回路)
题目链接 \(Description\) 给定平面上n个点,将这些点染成红or蓝色,要求每行.每列红色点与蓝色点数量的差的绝对值<=1.输出方案(保证有解). \(Solution\) 参考这 ...
随机推荐
- 剑指offer-第四章解决面试题的思路(栈的压入和弹出序列)
题目:输入两个整数序列,第一个序列表示栈的压入序列,请判断第二个序列是否为弹出序列. 思路:定义两个指针sPush和sPop分别指向两个整数序列的开头,借助一个辅助的栈,将第一个序列的数据依次压入栈中 ...
- goreplay(gor) golang 流量拷贝工具试用
1. 项目地址 https://github.com/buger/goreplay 2. 安装 wget https://github.com/buger/goreplay/releases/down ...
- maven命令行创建web项目报错:java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils
早上一上班就想新建一个web项目玩玩,没想到一敲命令创建就失败了,真是出师不利.各种折腾无果,当然我也可以用eclipse直接创建的,就是不甘心被这破问题给耍了.刚刚才发现问题原因,这个结果我也是醉了 ...
- css学习笔记之图像
图像与文本的对齐方式: vertical-align:text-top;表示的意思是图像的顶部和同一行的文本对齐,但文本不会超出图片的上边线. vertical-align:middle;表示的意思是 ...
- CAN总线应用
CAN总线的应用 1.汽车制造中的应用 应用CAN总线,可以减少车身布线,进一步节省了成本,由于采用总线技术,模块之间的信号传递仅需要两条信号线.布线局部化,车上除掉总线外其他所有横贯车身的线都不再需 ...
- juc线程池原理(四): 线程池状态介绍
<Thread之一:线程生命周期及五种状态> <juc线程池原理(四): 线程池状态介绍> 线程有5种状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态.线程池也有5种状态 ...
- PHP中GD库的使用
1.基本步骤 <?php /** * Created by PhpStorm. * User: jiqing * Date: 18-4-9 * Time: 上午9:34 * 熟悉步骤 */ // ...
- js keyup、keypress和keydown事件 详解
js keyup.keypress和keydown事件 详解 js keyup.keypress和keydown事件都是有关于键盘的事件 当一个按键被pressed 或released在每一个现代浏 ...
- 查询cad库中,所有程序leg引用的点的id,需要预先处理点表和程序表
select f1.pro_id,f1.pro_type, f1.code_fix_point, f1.code_type_fix_point, f1.code_fir,f2.code_icao,nv ...
- C# IP地址去掉端口号
string Ip1 = "192.168.0.199:7777"; string Ip2 = Ip1.Remove(Ip1.IndexOf(':'));