zoukankan      html  css  js  c++  java
  • CF547D Mike and Fish

    欧拉回路,巧妙的解法。

    发现每一个点$(x, y)$实际上是把横坐标和$x$和纵坐标$y$连一条线,然后代进去跑欧拉回路,这样里一条边对应了一个点,我们只要按照欧拉回路间隔染色即可。

    注意到原图可能并不是一个完全的欧拉图,但是度数为奇数的点只可能有偶数个,我们可以在连完边之后再把度数为奇数的点两两配对连边,这样子就是一个完全的欧拉图了。

    然后……这个图仍然可能不连通,所以每一个点都代进去搜一下。

    思考一下这样子为什么是对的,我们从一个点开始走,如果这个点染了一个颜色,那么这个点同一行或者是同一列的点都不要再染同一个颜色了,向别的地方走的意思就是不染相同的颜色,这样子看似贪心地染一定能求出所需要地答案,欧拉回路其实就是确定了一个染色的顺序,我们只要看一看走了正反哪一条边就可以确定染色了。

    时间复杂度应当是$O(n)$的,但是我还写了个离散化……

    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 2e5 + 5;
    const int inf = 1 << 30;
    
    int n, totx, toty, tot = 1, head[N << 1];
    int deg[N << 1], ax[N], ay[N], col[N];
    bool vis[N << 2];
    
    struct Edge {
        int to, nxt;
    } e[N << 2];
    
    inline void add(int from, int to) {
        e[++tot].to = to;
        e[tot].nxt = head[from];
        head[from] = tot;
    }
    
    struct Innum {
        int val, id;
        
        friend bool operator < (const Innum &x, const Innum &y) {
            if(x.val != y.val) return x.val < y.val;
            else return x.id < y.id;
        }
        
    } in[N];
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline void chkMax(int &x, int y) {
        if(y > x) x = y;
    }
    
    inline void discrete(int *arr, int preLen, int &nowLen) {
        in[0].val = -inf;
        for(int i = 1; i <= preLen; i++)
            in[i].val = arr[i], in[i].id = i;
        sort(in + 1, in + 1 + preLen);
        nowLen = 0;
        for(int i = 1; i <= preLen; i++) {
            if(in[i].val != in[i - 1].val) ++nowLen;
            arr[in[i].id] = nowLen;
        }
    }
    
    void dfs(int x) {
        for(int &i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to, t = i;
            if(vis[t] || vis[t ^ 1]) continue;
            vis[t] = 1;
            dfs(y);
        }
    }
    
    int main() {
        read(n);
        for(int i = 1; i <= n; i++) 
            read(ax[i]), read(ay[i]);
            
    /*    printf("%d
    ", n);
        for(int i = 1; i <= n; i++)
            printf("%d %d
    ", ax[i], ay[i]);        */
    
        discrete(ax, n, totx), discrete(ay, n, toty);
        for(int i = 1; i <= n; i++) {
            add(ax[i], ay[i] + totx), add(ay[i] + totx, ax[i]);
            ++deg[ax[i]], ++deg[ay[i] + totx];
        }
        
        int lst = 0;
        for(int i = 1; i <= totx + toty; i++) {
            if(!(deg[i] & 1)) continue;
            if(!lst) lst = i;
            else add(lst, i), add(i, lst), ++deg[i], ++deg[lst], lst = 0;
        }
        
        for(int i = 1; i <= totx + toty; i++)
            if(deg[i]) dfs(i);    
        
        for(int i = 1; i <= n; i++)
            putchar(vis[i << 1] ? 'r' : 'b');
        
        printf("
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    数据库事务隔离级别
    impala jdbc4的group by语句的bug,加上limit没错
    火狐不支持innerText属性,只支持innerHTML属性
    struts2.x + Tiles2.x读取多个xml 配置文件
    ids for this class must be manually assigned before calling save():Xxx
    整合ssh model $$_javassist_13 cannot be cast to javassist.util.proxy.Proxy
    火狐点击链接请求两次的问题
    C++——类和动态内存分配
    C++——使用类
    C++——对象和类
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9851516.html
Copyright © 2011-2022 走看看