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. Java 读取PDF中的表格

    一.概述 本文以Java示例展示读取PDF中的表格的方法.这里导入Spire.PDF for Javah中的jar包,并使用其提供的相关及方法来实现获取表格中的文本内容.下表中整理了本次代码使用到的主 ...

  2. C#与java TCP通道加密通信

    背景说明 公司收费系统需要与银行做实时代收对接,业务协议使用我们收费系统的标准.但是银行要求在业务协议的基础上,使用银行的加密规则. 采用MD5计算报文摘要,保证数据的完整性 采用RSA256对摘要进 ...

  3. 【UE4 C++】编程子系统 Subsystem

    概述 定义 Subsystems 是一套可以定义.自动实例化和释放的类的框架.可以将其理解为 GamePlay 级别的 Component 不支持网络赋值 4.22开始引入,4.24完善.(可以移植源 ...

  4. 【UE4 C++】 获取Actor、Controller、Pawn、Character

    获取 Actor TActorIterator 遍历 可以用于遍历 Actor,也可以用于遍历 Component for (TActorIterator<AStaticMeshActor> ...

  5. linux:桌面切换

    永久更改 字符模式:multi-user.target 图形模式:graphical.target systemctl get-default #查看默认模式 systemctl set-defaul ...

  6. Scrum Meeting 0605

    零.说明 日期:2021-6-5 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 困难 qsy PM&前端 暂无 重新设 ...

  7. filter tools

    // 过滤商品分类 Vue.filter("cateFilter", (data) => {   let tmp = ["一级分类", "二级分 ...

  8. Python里字符串Format时的一个易错“点”

    这是一篇很小的笔记,原因是我做学习通的时候见到了这个题: 当时看了一会儿发现没有符合自己想法的答案,然后就脑袋一热选了C,结果当然是错了... 看了一眼这个format的字符串对象,发现有个 {:7. ...

  9. 记一次CTF比赛过程与解题思路-MISC部分

    前言 最近好久没更新博客和公众号了,有朋友问是不是在憋大招,但我不好意思说其实是因为最近一段时间太懒了,一直在当咸鱼- 意识到很久没更新这个问题,我是想写点什么的,但好像一直当咸鱼也没啥可分享的,最近 ...

  10. Charles抓包 mock数据和rewrite功能

    一.mock数据 mock:在后端返回异常或需要=改前端展示的数据时可以模拟返回的response 1.1 抓到接口后 右击保存response到本地,后缀改成.json打开可以看到是把json保存下 ...