题目链接:点击打开链接
题意:
给定二维平面上的n个点的坐标
问:
把每个点用红色或蓝色染色, 使得 水平共线(或者垂直共线)的 点 中红色与蓝色数量差不超过1.
思路:
我们建一个二部图,X集是x轴,Y集是y轴
那么点(1,5)就是 x集的 1向 y集的 5连一条边。
此时点就是用边来表示的,那我们的任务就是给边染色。
使得:
对于二部图中任意一个点, 点所连接的红边和蓝边数量差不超过1.
那么我们可以认为这个点的入边就是红色,出边就是蓝色。显然这就是一个欧拉路径。
所以爆搜欧拉路径即可。
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if (x>9) pt(x / 10);
putchar(x % 10 + '0');
}
const int N = 2e5 + 10;
typedef long long ll;
struct Edge{
int from, to, col, nex;
}edge[N << 2];
int head[N<<1], edgenum;
void add(int u, int v){
Edge E = { u, v, -1, head[u] };
edge[edgenum] = E;
head[u] = edgenum++;
}
int n;
int vis[N << 2];
int du[N << 2];
void dfs(int u){
// printf("%d ", u);
for (int i = head[u]; ~i; i = head[u] = edge[i].nex){
if (edge[i].col != -1)continue;
int v = edge[i].to;
edge[i].col = u < v;
edge[i ^ 1].col = -2;
vis[u]++; vis[v]++;
dfs(v);
break;
}
}
vector<int>X, Y;
int x[N], y[N];
int main(){
rd(n);
memset(head, -1, sizeof head); edgenum = 0;
for (int i = 1; i <= n; i++){
rd(x[i]); rd(y[i]);
X.push_back(x[i]);
Y.push_back(y[i]);
}
sort(X.begin(), X.end());
sort(Y.begin(), Y.end());
X.erase(unique(X.begin(), X.end()), X.end());
Y.erase(unique(Y.begin(), Y.end()), Y.end());
for (int i = 1; i <= n; i++){
x[i] = lower_bound(X.begin(), X.end(), x[i]) - X.begin() ;
y[i] = lower_bound(Y.begin(), Y.end(), y[i]) - Y.begin() + n;
du[x[i]]++; du[y[i]]++;
add(x[i], y[i]); add(y[i], x[i]);
}
// for (int i = 0; i <= 2 * n; i++)printf("(%d,%d)\n", i, du[i]);
for (int i = 0; i <= 2 * n; i++)
if (du[i] & 1 && vis[i] < du[i]){
// printf("odd dfs %d: ", i);
dfs(i);
// puts("");
}
for (int i = 0; i <= 2 * n; i++)
if (du[i] && vis[i] < du[i]){
// printf("normal dfs %d: ", i);
dfs(i);
// puts("");
}
for (int i = 0; i < edgenum; i ++)
if (edge[i].col >= 0)
putchar(edge[i].col ? 'r' : 'b');
return 0;
}
/*
4
1 1
1 2
2 1
2 2
7
1 0
2 0
2 1
0 2
1 2
2 2
2 3
*/