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. PHP伪协议与文件包含漏洞1

    PHP文件包含漏洞花样繁多,需配合代码审计. 看能否使用这类漏洞时,主要看: (1)代码中是否有include(),且参数可控: 如: (2)php.ini设置:确保 allow_url_fopen= ...

  2. 重学c#系列——list(十二)

    前言 简单介绍一下list. 正文 这里以list为介绍. private static readonly T[] s_emptyArray = new T[0]; public List() { t ...

  3. LeetCode:动态规划

    动态规划 动态规划永远的神 这部分主要是学习了 labuladong 公众号中对于动态规划的讲解 刷了些 leetcode 题,在此做一些记录,不然没几天就忘光光了 题目 这部分内容直接上题目了,解题 ...

  4. [技术博客] 软工-Ruby on Rails前端工具链的配置以及对Web应用结构设计的一点思考

    一.相关工具链简介 HAML HAML是专门面向Ruby on Rails模版语法设计的一门标记语言,其结合RoR的views部分模版语法的特点,对原来的*.html.erb(嵌入Ruby代码的HTM ...

  5. Ubuntu14.04安装ia32-libs报错

    安装编译环境的时候报错 sudo apt-get install ia32-libs Reading package lists... Done Building dependency tree Re ...

  6. poj 3041 Asteroids(最小点覆盖)

    题意: N*N的矩阵,有K个敌人,坐标分别是(C1,C1),.....,(Rk,Ck). 有一个武器,每发射一次,可消掉某行或某列上的所有的敌人. 问消灭所有敌人最少需要多少发. 思路: 二分建图:左 ...

  7. IELTS6 2020.7 Translation

    原文 <三国演义>(The Romance of the ThreeKingdoms)是中国一部著名的历史小说,写于十四世纪.这部文学作品以三国时期的历史为背景,描写了从公元二世纪下半叶到 ...

  8. java线程同步以及对象锁和类锁解析(多线程synchronized关键字)

    一.关于线程安全 1.是什么决定的线程安全问题? 线程安全问题基本是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的:若有多个线 ...

  9. selenium2.x 与 selenium3.x 最大区别

    一.selenium2.x 与 selenium3.x 最大区别 (1) 从3.0版本selenium开始使用火狐浏览器完成web自动化就需要用到驱动包了. (2) 而2.0版本的selenium使用 ...

  10. Linux usb 6. HC/UDC 测试

    目录 1. 背景介绍 2. Device (gadget zero) 2.1 gadget zero 创建 2.2 SourceSink Function 2.3 Loopback Function ...