zoukankan      html  css  js  c++  java
  • CF 547 D. Mike and Fish

    D. Mike and Fish

    http://codeforces.com/contest/547/problem/D

    题意:

      给定平面上n个点,将这些点染成红或者蓝色,要求每行、每列红色点与蓝色点数量的差的绝对值<=1。输出方案(保证有解)。

    分析:

      参考popoqqq的博客

      将每行每列分别看做一个点,给定的每个点(x,y)拆成x->y的边,那么连边后的图是一个二分图。

      这样我们可以将边染色,使得与每个点相连的两种颜色差<=1。

      于是对于所有的欧拉回路,我们可以直接交替染色。

      但是会有度数为奇数的点,这样的点一定有偶数个,我们对其两两配对连边,这样所有奇度数的点度数就都为偶数了。

      对于每个连通块,选一个初始度数为奇数的点(若没有则任选度数为偶数的点),求一条欧拉回路(若是奇度数点则应先走与配对的奇度数点相连的边),将路径上的边交替染色即可。

    正确性: 

      对于一条欧拉回路,除起点外每个点相连的红边与蓝边数是相同的。对于起点,欧拉回路的第一条边和最后一条边的颜色可能是相同的。

      若起点初始度数为奇数,由于先走了与新连出的边,所以就算第一条和最后一条边的颜色相同也没关系。(同色的话由于有影响的点在同行同列,一定连通,所以整个连通块只会额外多出一条边颜色不同)。

      若起点初始度数为偶数,则连通块是一个二分图,第一条和最后一条边的颜色一定不相同。

      还有一种神奇的做法:AOQNRMGYXLMVcaoyi0905

    代码:

     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] = '';
    72     puts(ans + 1);
    73     return 0;
    74 }
  • 相关阅读:
    考虑浏览器兼容的文件上传(IE8不支持FormData)
    IDEA tomcat 部署WEB项目
    如何在springcloud分布式系统中实现分布式锁?
    ABAP DEMO33 选择周的搜索帮助
    ABAP函数篇1 日期函数
    ABAP函数篇2 测试DATE_CONVERT_TO_FACTORYDATE
    增强篇7 判断标准屏幕能否做屏幕增强
    增强篇6 CMOD增强删除
    ABAP DEMO 年月的搜索帮助
    HoloLens开发手记-配置开发环境 Install the tools
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9839274.html
Copyright © 2011-2022 走看看