Codeforces 547D - Mike and Fish(欧拉回路)
首先考虑将题目中的条件转化为图论的语言。看到“行”“列”,我们很自然地想到二分图中行、列转点,点转边的套路,对于每一行 \(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(欧拉回路)的更多相关文章
- 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.547D.Mike and Fish(思路 欧拉回路)
题目链接 \(Description\) 给定平面上n个点,将这些点染成红or蓝色,要求每行.每列红色点与蓝色点数量的差的绝对值<=1.输出方案(保证有解). \(Solution\) 参考这 ...
- Codeforces 547D Mike and Fish
Description 题面 题目大意:有一个的网格图,给出其中的 \(n\) 个点,要你给这些点染蓝色或红色,满足对于每一行每一列都有红蓝数量的绝对值之差不超过1 Solution 首先建立二分图, ...
- CodeForces 547D Mike and Fish 思维
题意: 二维平面上给出\(n\)个点,然后对每个点进行染色:红色和蓝色,要求位于同一行或同一列的点中,红色点和蓝色点的个数相差不超过1 分析: 正解是求欧拉路径,在这篇博客中看到一个巧妙的思路: 对于 ...
- Codeforces 247D Mike and Fish
Mike and Fish 我们可以把这个模型转换一下就变成有两类点,一类是X轴, 一类是Y轴, 每个点相当于对应的点之间建一条边, 如果这条边变红两点同时+1, 变蓝两点同时-1. 我们能发现这个图 ...
- cf547D. Mike and Fish(欧拉回路)
题意 题目链接 Sol 说实话这题我到现在都不知道咋A的. 考试的时候是对任意相邻点之间连边,然后一分没有 然后改成每两个之间连一条边就A了.. 按说是可以过掉任意坐标上的点都是偶数的数据啊.. #i ...
- 547D Mike and Fish
传送门 分析 见正睿10.3笔记 代码 #include<iostream> #include<cstdio> #include<cstring> #include ...
- CF 547 D. Mike and Fish
D. Mike and Fish http://codeforces.com/contest/547/problem/D 题意: 给定平面上n个点,将这些点染成红或者蓝色,要求每行.每列红色点与蓝色点 ...
- 「CF547D」 Mike and Fish
「CF547D」 Mike and Fish 传送门 介绍三种做法. \(\texttt{Solution 1}\) 上下界网络流 我们将每一行.每一列看成一个点. 两种颜色的数量最多相差 \(1\) ...
随机推荐
- 项目优化之v-if
前言: 在vue项目中,由于功能比较多,需要各种条件控制某个功能.某个标签.表格中的某一行是否显示等,需要使用大量的v-if来判断条件. 例如: <div v-if="isShow(a ...
- 【数据结构与算法Python版学习笔记】树——相关术语、定义、实现方法
概念 一种基本的"非线性"数据结构--树 根 枝 叶 广泛应用于计算机科学的多个领域 操作系统 图形学 数据库 计算机网络 特征 第一个属性是层次性,即树是按层级构建的,越笼统就越 ...
- ubuntu20.04 使用root用户登录
1.设置root用户密码 执行 sudo passwd root 然后输入设置的密码,输入两次,这样就完成了设置root用户密码了 2.修改配置文件 执行 sudo vim /usr/share/li ...
- Stack2 攻防世界题目分析
---XCTF 4th-QCTF-2018 前言,怎么说呢,这题目还是把我折磨的可以的,我一开始是没有看到后面的直接狙击的,只能说呢. 我的不经意间的粗心,破坏了你许多的温柔 1.气的我直接检查保护: ...
- Noip模拟12 2021.7.12
T1 interval 亏得昨天晚上改掉了T3并且理解了单调栈,今天一扫这题目就知道要用啥了. 先预处理出以a[i]为最大值的最大左右区间.然后再将a[i]取%!!!是的,要不然会影响单调栈的使用.. ...
- 计算机中的contex理解
原文链接 https://www.xuebuyuan.com/2016635.html 1.其实简单的说就是跟当前主题有关的所有内容. 2.如说到程序的上下文,就是当前这段程序之上和之下的程序段.因 ...
- 算法:汉诺塔问题(Tower of Brahma puzzle)
一.算法背景 最早发明这个问题的人是法国数学家爱德华·卢卡斯.传说越南河内某间寺院有三根银棒(A, B, C),上串 64 个金盘. 寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子:预言说当这 ...
- 最短路径算法:弗洛伊德(Floyd-Warshall)算法
一.算法介绍 Floyd-Warshall算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存 ...
- 探索Mybatis之JDK动态代理:探究Proxy.newProxyInstance()生成的代理类解析
Mybatis的Mapper接口UserMapper 1 package com.safin.Mapper; 2 3 import com.safin.Pojo.User; 4 5 import ja ...
- linux shell 函数返回值问题(超过255)
最近再写一个shell测试的时候出现问题,函数返回值异常 用shell计算斐波那契数列数列,写了一个shell函数,然后调用的,验证的时候我只随便计算了几个数(10以内),确认结果是正确的就提交了,后 ...