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 thing about him is he has an infinite number of blue and red fish.
He has marked n distinct points in the plane. i-th point is point (xi, yi). He wants to put exactly one fish in each of these points such that the difference between the number of red fish and the blue fish on each horizontal or vertical line is at most 1.
He can't find a way to perform that! Please help him.
The first line of input contains integer n (1 ≤ n ≤ 2 × 105).
The next n lines contain the information about the points, i-th line contains two integers xi and yi (1 ≤ xi, yi ≤ 2 × 105), the i-th point coordinates.
It is guaranteed that there is at least one valid answer.
Output
Print the answer as a sequence of n characters 'r' (for red) or 'b' (for blue) where i-th character denotes the color of the fish in the i-th point.
Examples
4
1 1
1 2
2 1
2 2
brrb
3
1 1
1 2
2 1
brr
题意:给定二维坐标,求一种合法的染色情况,使得每一行的颜色差异<=1;每一列也是。
思路:想不到。(不过不是第一次见了,多校也见过)。把点转化为边,那么就是每个点的两种颜色存疑最多为1,把两种颜色看成入边和出边,则和欧拉路,欧拉回路有些联系。 把度数为1的加“虚边”,染色即可。
自己的版本:离散化; 一个连通块,最多两个奇点,如果有,找出来加边,然后dfs。
(dfs的之后需要加地址符,防止多次访问无效边,会T31
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn],cnt,vis[maxn],ans[maxn];
int x[maxn],y[maxn],a[maxn],tot1,tot2,ind[maxn],used[maxn];
int q[maxn],top,opt;
void add(int u,int v)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void dfs(int u)
{
if(used[u]) return ;
if(ind[u]&) q[++top]=u; used[u]=;
for(int i=Laxt[u];i;i=Next[i]) dfs(To[i]);
}
void dfs1(int u,int f)
{
for(int &i=Laxt[u];i;i=Next[i]){ //加个地址符,防止被稠密图卡。
if(!vis[i]){
ans[i/]=opt; vis[i]=vis[i^]=;
dfs1(To[i],i);
}
}
ans[f/]=opt; opt^=;
}
int main()
{
int N; scanf("%d",&N);
rep(i,,N) scanf("%d%d",&x[i],&y[i]);
rep(i,,N) a[++tot1]=x[i];
sort(a+,a+tot1+);tot1=unique(a+,a+tot1+)-(a+);
rep(i,,N) x[i]=lower_bound(a+,a+tot1+,x[i])-a;
rep(i,,N) a[++tot2]=y[i];
sort(a+,a+tot2+); tot2=unique(a+,a+tot2+)-(a+);
rep(i,,N) y[i]=lower_bound(a+,a+tot2+,y[i])-a;
cnt=;
rep(i,,N) {
add(x[i],y[i]+tot1);
add(y[i]+tot1,x[i]);
ind[x[i]]++; ind[y[i]+tot1]++;
}
rep(i,,tot1+tot2) {
if(!used[i]){
top=; dfs(i);
rep(i,,top){
add(q[i],q[i+]); add(q[i+],q[i]); i++;
}
opt=;
if(top) dfs1(q[],); else dfs1(i,);
}
}
rep(i,,N) putchar(ans[i]?'b':'r');
return ;
}
看了std:不离散化;而且任意的奇点偶可以加边,效果不变。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn],cnt=,vis[maxn],ans[maxn];
int x[maxn],y[maxn],a[maxn],tot1,tot2,ind[maxn];
int q[maxn],top,opt;
inline char gc(){
static char buf[<<],*S,*T;
if(S==T){T=(S=buf)+fread(buf,,<<,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=,f=;char ch=gc();
while(ch<''||ch>''){if(ch=='-') f=-;ch=gc();}
while(ch>=''&&ch<='') x=x*+ch-'',ch=gc();
return x*f;
}
void add(int u,int v)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void dfs(int u)
{
for(int &i=Laxt[u];i;i=Next[i]){
if(!vis[i]&&!vis[i^]){
vis[i]=; dfs(To[i]);
}
}
}
int main()
{
int N; scanf("%d",&N);
rep(i,,N) x[i]=read(),y[i]=read()+2e5;
rep(i,,N) {
add(x[i],y[i]);
add(y[i],x[i]);
ind[x[i]]++; ind[y[i]]++;
}
int lst=;
rep(i,,4e5){
if(ind[i]&){
if(lst) add(lst,i),add(i,lst),lst=;
else lst=i;
}
}
rep(i,,4e5) if(ind[i])dfs(i);
rep(i,,N) putchar(vis[i<<]?'b':'r');
return ;
}
CodeForces - 547D: Mike and Fish (转化为欧拉回路)(优化dfs稠密图)(定向问题)的更多相关文章
- Codeforces 547D - Mike and Fish(欧拉回路)
Codeforces 题目传送门 & 洛谷题目传送门 首先考虑将题目中的条件转化为图论的语言.看到"行""列",我们很自然地想到二分图中行.列转点,点转 ...
- 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. 我们能发现这个图 ...
- 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\) ...
- hdu4135-Co-prime & Codeforces 547C Mike and Foam (容斥原理)
hdu4135 求[L,R]范围内与N互质的数的个数. 分别求[1,L]和[1,R]和n互质的个数,求差. 利用容斥原理求解. 二进制枚举每一种质数的组合,奇加偶减. #include <bit ...
随机推荐
- java入门书籍很少介绍的java知识
1.java中数组的长度可以用.length来确定 2.java中的Arrays类可以对数组进行轻松的操作 (1).包名:import java.util.Arrays (2).Arrays.sort ...
- Android GridView 分页加载数据
android UI 往右滑动,滑动到最后一页就自动加载数据并显示 如图: package cn.anycall.ju; import java.util.ArrayList; import java ...
- Codeforces 895C - Square Subsets
895C - Square Subsets 思路:状压dp. 每个数最大到70,1到70有19个质数,给这19个质数标号,与状态中的每一位对应. 状压:一个数含有这个质因子奇数个,那么他状态的这一位是 ...
- C#匿名对象序列化
//匿名对象序列化 }; Console.WriteLine(JsonConvert.SerializeObject(obj)); //匿名集合序列化 List<object> list ...
- Java基础八--构造函数
Java基础八--构造函数 一.子父类中构造函数的特点 1.1 为什么在子类构造对象时,发现,访问子类构造函数时,父类也运行了呢? 原因是:在子类的构造函数中第一行有一个默认的隐式语句. super( ...
- VMware 怎么判断哪台机子试图用混杂模式且不成功
主要是看个log, 然后推断虚拟端口号 The VMkernel logs at /var/log/vmkernel or /var/log/messages contain entries simi ...
- jquery ajax中 php前台后台文件中编辑都是uft-8,返回数据还是乱码
jquery ajax中 前台后台文件中编辑都是uft-8,返回数据还是乱码 解决如下: 在后台处理文件里面需要再加编辑 header("Content-Type:text/html;cha ...
- 【转】ArcGIS API for Silverlight/WPF 2.1学习笔记(二)
五.Graphics layer 1.新增Graphics layer Graphics layer用于显示用户自定义绘制的点.线.面图形.使用时确保xaml文件中Graphics layer定义 ...
- PHP函数总结 (四)
<?php/** * 引用参数: * 1.PHP默认按值传递参数,父程序(调用函数)与子程序(函数)的数值分别存储与不同的内存区块: * 2.引用传递参数,加符号 & :它是把父程序的数 ...
- 『cs231n』卷积神经网络工程实践技巧_上
概述 数据增强 思路:在训练的时候引入干扰,在测试的时候避免干扰. 翻转图片增强数据. 随机裁切图片后调整大小用于训练,测试时先图像金字塔制作不同尺寸,然后对每个尺寸在固定位置裁切固定大小进入训练,最 ...