zoukankan      html  css  js  c++  java
  • CF429E Points and Segments 构造、欧拉回路

    传送门


    如果把一条线段([l,r])看成一条无向边((l,r+1)),从(l)走到(r+1)表示线段([l,r])染成红色,从(r+1)走到(l)表示线段([l,r])染成蓝色,那么题目等价于给每一条边定下方向,使得对于所有点,从左往右经过的次数和从右往左经过的次数差的绝对值不超过(1)

    对于直线上所有奇数度的点,从左往右两两配对,那么就是要求对于所有的点从左往右经过的次数等于从右往左经过的次数。不难想到这是一个欧拉图。求解欧拉回路给边定向即可。

    注意直线上的奇数度的点不能随意配对,因为如果对于(A<B<C<D)四个奇数入度的点,连((A,D))((B,C)),而找到的欧拉回路方案中边的方向为(A ightarrow D , B ightarrow C),那么在这两条边去掉之后线段([B,C])从左往右的次数比从右往左的次数少(2),就不符合题意了。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iomanip>
    #include<set>
    #include<vector>
    //This code is written by Itst
    using namespace std;
    
    inline int read(){
        int a = 0;
        char c = getchar();
        while(!isdigit(c))
            c = getchar();
        while(isdigit(c)){
            a = a * 10 + c - 48;
            c = getchar();
        }
        return a;
    }
    
    #define PII pair < int , int >
    const int MAXN = 2e5 + 7;
    multiset < PII > Edge[MAXN];
    int lsh[MAXN] , in[MAXN] , N , cntL;
    vector < PII > tmp;
    bool col[MAXN];
    
    void dfs(int x){
        for(auto t = Edge[x].begin() ; !Edge[x].empty() ; t = Edge[x].begin()){
            int a = t->first , b = t->second;
            Edge[x].erase(t);
            Edge[a].erase(Edge[a].find(PII(x , -b)));
            if(b > 0) col[b] = 1;
            dfs(a);
        }
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in","r",stdin);
        //freopen("out","w",stdout);
    #endif
        N = read();
        for(int i = 1 ; i <= N ; ++i){
            int a = read() , b = read() + 1;
            tmp.push_back(PII(a , b));
            lsh[++cntL] = a; lsh[++cntL] = b;
        }
        sort(lsh + 1 , lsh + cntL + 1);
        cntL = unique(lsh + 1 , lsh + cntL + 1) - lsh - 1;
        for(int i = 0 ; i < N ; ++i){
            int p = lower_bound(lsh + 1 , lsh + cntL + 1 , tmp[i].first) - lsh , q = lower_bound(lsh + 1 , lsh + cntL + 1 , tmp[i].second) - lsh;
            Edge[p].insert(PII(q , i + 1));
            Edge[q].insert(PII(p , -i - 1));
            in[p] ^= 1; in[q] ^= 1;
        }
        int pre = 0;
        for(int i = 1 ; i <= cntL ; ++i)
            if(in[i])
                if(!pre) pre = i;
                else{
                    Edge[pre].insert(PII(i , 0));
                    Edge[i].insert(PII(pre , 0));
                    ++in[pre]; ++in[i];
                    pre = 0;
                }
        for(int i = 1 ; i <= cntL ; ++i)
            if(!Edge[i].empty())
                dfs(i);
        for(int i = 1 ; i <= N ; ++i)
            cout << col[i] << ' ';
        return 0;
    }
    
  • 相关阅读:
    做代码的曲线问题
    全书目录
    关于《Delphi源代码分析》的讨论
    说说“从编程到工程”专栏的由来
    CF285E Positions in Permutations
    CF264B Good Sequences
    CF115E Linear Kingdom Races
    CF633F The Chocolate Spree
    CF767C Garland
    CF559C Gerald and Giant Ches
  • 原文地址:https://www.cnblogs.com/Itst/p/10464478.html
Copyright © 2011-2022 走看看