D. Mike and fish
Http://codeforces.com/contest/547/problem/D
Question:
Given N points on the plane, these points are red or blue, and the absolute value of the difference between the number of red points and the number of blue points in each row and column is required <= 1. Output Scheme (solution guaranteed ).
Analysis:
Refer to the popoqqq blog
Consider each column of each row as a vertex. If each vertex (X, Y) is split into an edge of X-> Y, the graph after the edge is connected is a bipartite graph.
In this way, we can dye edges so that the two colors connected to each vertex are less than or equal to 1.
So for all the Euler's circuits, We can dye them alternately.
However, there will be an odd number of points, such points must have an even number, we pair them to the connected edge, so that all the odd degrees of points are even.
For each connected block, select a vertex with an odd initial degree (if not, select a vertex with an even degree ), find an Euler Loop (if it is an odd degree pair, First connect the edge with the paired odd degree pair), and alternately dye the edges on the path.
Correctness:
For an Euler loop, the number of red and blue edges connected to each vertex except the starting point is the same. For the starting point, the first side of the Euler loop and the last side may have the same color.
If the initial degree of the start point is an odd number, the color of the first and last edge is the same as that of the newly connected edge. (If the same color is used, the affected points must be connected to the same column in the same row. Therefore, the entire connected block only has one additional edge color ).
If the initial degree of the start point is an even number, the connected block is a bipartite graph, and the color of the first and last edge must be different.
There is also a magic way: aoqnrmgyxlmv, caoyi0905
Code:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue>10 #include<map>11 #define fi(s) freopen(s,"r",stdin);12 #define fo(s) freopen(s,"w",stdout);13 using namespace std;14 typedef long long LL;15 16 inline int read() {17 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1;18 for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f;19 }20 21 const int N = 400005;22 const int D = 2e5;23 24 struct Edge{25 int to, nxt, id;26 }e[N << 1];27 int head[N], deg[N], A[N], sk[N], En = 1, top;28 bool ve[N << 1], vd[N];29 char ans[N];30 31 void add_edge(int u,int v,int id) {32 ++En; e[En].to = v, e[En].id = id, e[En].nxt = head[u]; head[u] = En;33 ++En; e[En].to = u, e[En].id = id, e[En].nxt = head[v]; head[v] = En;34 deg[u] ++, deg[v] ++;35 }36 37 void dfs(int u) {38 vd[u] = true;39 for (int i=head[u]; i; i=e[i].nxt) {40 if (!ve[i]) {41 ve[i] = ve[i ^ 1] = true; head[u] = i;42 dfs(e[i].to);43 sk[++top] = e[i].id; i = head[u];44 }45 }46 }47 48 int main() {49 int n = read(), cnt = 0;50 for (int i=1; i<=n; ++i) {51 int u = read(), v = read() + D;52 add_edge(u, v, i);53 }54 for (int i=1; i<=(D<<1); ++i) 55 if (deg[i] & 1) A[++cnt] = i;56 for (int i=1; i<=cnt; i+=2) 57 add_edge(A[i], A[i + 1], 0);58 59 for (int i=1; i<=cnt; ++i) {60 if (!vd[A[i]]) {61 dfs(A[i]);62 while (top) ans[sk[top]] = top & 1 ? ‘b‘ : ‘r‘, top --;63 }64 }65 for (int i=1; i<=(D<<1); ++i) {66 if (!vd[i]) {67 dfs(i);68 while (top) ans[sk[top]] = top & 1 ? ‘b‘ : ‘r‘, top --;69 }70 }71 ans[n + 1] = ‘\0‘;72 puts(ans + 1);73 return 0;74 }
Cf 547 D. Mike and fish