Codeforces 题目传送门 & 洛谷题目传送门

首先考虑将题目中的条件转化为图论的语言。看到“行”“列”,我们很自然地想到二分图中行、列转点,点转边的套路,对于每一行 \(x\) 新建一个点 \(R(x)\),对于每一列 \(x\) 也新建一个点 \(C(y)\)。考虑对于点 \((x_i,y_i)\),若其被染上红色,就连边 \(R(x_i)\to C(y_i)\),否则连边 \(C(y_i)\to R(x_i)\)。那么显然对于每一行而言,其红色格子的个数就是该行所对应的点的出度,其蓝色格子的个数就是该行所对应的点的入度;对于每一列而言,其红色格子的个数就是该行所对应的点的入度,其蓝色格子的个数就是该行所对应的点的出度。

因此我们可将题目转化为:给定一张二分图,要求给每条边定向,使每个点入度与出度之差的绝对值不超过 \(1\)。

我们不妨先考虑原题的一个弱化版本。假设原图中所有点度数都是偶数,那么我们要求一个无向图,使得每个点的入度等于出度。这显然可以用欧拉回路解决,由于每个点度数都是偶数,因此图的每个连通块的导出子图都存在欧拉回路,那么我们对于每个连通块跑一遍欧拉回路,假设为 \(v_1\to v_2\to v_3\to\dots\to v_k\to v_1\),那么我们只需对于 \(\forall i\in [1,k]\) 将 \(v_i\) 与 \(v_{i+1}\) 之间的边定向为 \(v_i\to v_{i+1}\) 即可,因为 \(\forall i\in [1,k]\),显然 \(v_{i-1}\to v_i\) 的边会为 \(v_i\) 的入度产生 \(1\) 的贡献,\(v_{i}\to v_{i+1}\) 的边会为 \(v_i\) 的出度产生 \(1\) 的贡献,因此 \(v_i\) 的入度永远等于出度,符合题目要求。

最后考虑原题,本题一个巧妙之处就在于奇点怎么处理。显然对于一个奇点而言,我们要求它的出度与入度之差为 \(\pm 1\),而我们希望它的出度与入度之差为 \(0\),这样就能归约到弱化版了。因此我们考虑建立一个虚点,将所有奇点与该虚点之间连边,显然对于原图一个合法的定向方式,我们总能控制这些奇点与虚点连边的方向使得每个奇点的入度都等于出度。又根据有向图 \(\sum indeg_i=\sum outdeg_i\) 可知该虚点的入度也等于出度,故我们在新图上跑欧拉回路即可。

时间复杂度线性。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int DELTA=2e5+2;
int n,deg[DELTA*2+5],hd[DELTA*2+5],to[DELTA*6+5],nxt[DELTA*6+5],ec=1;
void adde(int u,int v){to[++ec]=v;nxt[ec]=hd[u];hd[u]=ec;}
int vis[DELTA*3+5];
void dfs(int x){
for(int &e=hd[x];e;e=nxt[e])
if(!vis[e>>1]) vis[e>>1]=1+(x<=DELTA),dfs(to[e]);
}
int main(){
scanf("%d",&n);
for(int i=1,x,y;i<=n;i++){
scanf("%d%d",&x,&y);++deg[x];++deg[y+DELTA];
adde(x,y+DELTA);adde(y+DELTA,x);
}
for(int i=1;i<=DELTA*2;i++)
if(deg[i]&1) adde(0,i),adde(i,0);
for(int i=1;i<=DELTA;i++) dfs(i);
for(int i=1;i<=n;i++) putchar((vis[i]==1)?'r':'b');
return 0;
}

Codeforces 547D - Mike and Fish(欧拉回路)的更多相关文章

  1. 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 ...

  2. Codeforces.547D.Mike and Fish(思路 欧拉回路)

    题目链接 \(Description\) 给定平面上n个点,将这些点染成红or蓝色,要求每行.每列红色点与蓝色点数量的差的绝对值<=1.输出方案(保证有解). \(Solution\) 参考这 ...

  3. Codeforces 547D Mike and Fish

    Description 题面 题目大意:有一个的网格图,给出其中的 \(n\) 个点,要你给这些点染蓝色或红色,满足对于每一行每一列都有红蓝数量的绝对值之差不超过1 Solution 首先建立二分图, ...

  4. CodeForces 547D Mike and Fish 思维

    题意: 二维平面上给出\(n\)个点,然后对每个点进行染色:红色和蓝色,要求位于同一行或同一列的点中,红色点和蓝色点的个数相差不超过1 分析: 正解是求欧拉路径,在这篇博客中看到一个巧妙的思路: 对于 ...

  5. Codeforces 247D Mike and Fish

    Mike and Fish 我们可以把这个模型转换一下就变成有两类点,一类是X轴, 一类是Y轴, 每个点相当于对应的点之间建一条边, 如果这条边变红两点同时+1, 变蓝两点同时-1. 我们能发现这个图 ...

  6. cf547D. Mike and Fish(欧拉回路)

    题意 题目链接 Sol 说实话这题我到现在都不知道咋A的. 考试的时候是对任意相邻点之间连边,然后一分没有 然后改成每两个之间连一条边就A了.. 按说是可以过掉任意坐标上的点都是偶数的数据啊.. #i ...

  7. 547D Mike and Fish

    传送门 分析 见正睿10.3笔记 代码 #include<iostream> #include<cstdio> #include<cstring> #include ...

  8. CF 547 D. Mike and Fish

    D. Mike and Fish http://codeforces.com/contest/547/problem/D 题意: 给定平面上n个点,将这些点染成红或者蓝色,要求每行.每列红色点与蓝色点 ...

  9. 「CF547D」 Mike and Fish

    「CF547D」 Mike and Fish 传送门 介绍三种做法. \(\texttt{Solution 1}\) 上下界网络流 我们将每一行.每一列看成一个点. 两种颜色的数量最多相差 \(1\) ...

随机推荐

  1. oo第一单元学习总结

    写在开头: 第一次接触面向对象思想和java语言,在学习以及完成作业的过程经历了一个比较痛苦的过程, 虽然在每次写作业时总是会有一些小小的抱怨,虽然写出的代码还是很差, 但是看到自己有所进步,还是感觉 ...

  2. MyBatis源码分析(三):MyBatis初始化(配置文件读取和解析)

    一. 介绍MyBatis初始化过程 项目是简单的Mybatis应用,编写SQL Mapper,还有编写的SqlSessionFactoryUtil里面用了Mybatis的IO包里面的Resources ...

  3. SPOJ GSS8 - Can you answer these queries VIII | 平衡树

    题目链接 这一道题的修改操作用平衡树都很容易实现,难处理的是询问操作. 要想解决询问操作,只要知道如何在平衡树上快速合并左右两个区间的答案即可. 设$Ans_{[l,r]}^k=\sum\limits ...

  4. JAVA笔记4__static关键字/对象数组/foreach/方法的可变参数

    /** * static关键字:修饰属性(实质就是全局变量).方法(无需本类的对象即可调用此方法).类. * 1.static方法只能调用static方法 * 2.static方法只能访问static ...

  5. Memory Analyzer Tool 使用

    转载出处:https://wensong.iteye.com/blog/1986449 最近一段时间一直在研究热部署,热部署中涉及到一个比较头痛的问题就是查内存泄露(Memory Leak),于是乎在 ...

  6. (二)lamp环境搭建之编译安装mysql

    mysql 编译安装1,在网站上下载: wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.15.tar.gz 2,安装cmake ...

  7. clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)

    修改文件 /etc/sysconfig/nfs将#MOUNTD_PORT=892开启防火墙端口:firewalld-cmd --add-port=892/tcp

  8. k8s入坑之路(13)kubernetes重要资源(namespace隔离 resources资源管理 label)

    Namespace --- 集群的共享与隔离 语言中namespace概念 namespace核心作用隔离 以上是隔离的代码.namespace隔离的是: 1.资源对象的隔离:Service.Depl ...

  9. Matlab+Qt开发笔记(二):Qt打开mat文件显示读取的数据

    前言   介绍了基础环境,最终是为了读取显示.mat文件,本篇读取mat文件并显示.   补充   测试的mat文件是double类型的. Matlab库数据类型 变量类型:matError,错误变量 ...

  10. JetBrains IntelliJ IDEA汉化

    JetBrains IntelliJ IDEA汉化 开启 IntelliJ IDEA,点击右下角Configure菜单,选择 Plugins.在弹出的 Plugins窗口里,切换至 Marketpla ...