zoukankan      html  css  js  c++  java
  • 转化欧拉回路(难题)-UESTC-1957励志的猴子

    励志的猴子

    Time Limit: 1000 MS     Memory Limit: 256 MB
    Submit Status

    上图是2013南京亚青会吉祥物圆圆。自从它诞生以来,它就被吐槽为最丑吉祥物。即使如此,它仍然坚强的活着,并且……它还学会了人类的坐标系、画画和数学,成为了猴界的全才。看到它这么努力,你还有理由不努力吗!

    虽然如此努力,圆圆受限于猴子的脑容量,还是差了一点——它只能掌握一维坐标系,画画只能分辨两种颜色,数学上只会不等式,只能认识整数。这一天,圆圆很无聊,于是它拿起一维坐标纸,想在纸上画n条线段,第i条线段从坐标轴的xi延伸到yi(包括端点)。

    励志的圆圆想要展示一下自己的智商,它用红蓝彩笔画下这n条线段,并且希望对于坐标轴上任意一个点,经过它的红线和蓝线数量的绝对值之差小于等于1.如果某个点是线段的端点,则这条线段也算作经过该点。

    不过这时,圆圆发现自己的算数能力还是有点差,于是它找到了你,希望你确定每条线段的颜色,来满足它的奇思妙想。

    Input

    第一行一个整数n(1 ≤ n ≤ 100000), 表示圆圆画的线段的数量。

    接下来n行,每行两个整数x,y( 0≤ x ≤ y ≤ 109109 ),表示一条线段从x延伸到y。

    Output

    输出n个数,用空格隔开,如果第i条线段是蓝色,则输出0,否则输出1.

    如果有多组解,输出一组即可。

    如果找不到答案,输出一个数-1.

    Sample input and output

    Sample InputSample Output
    2
    1 2
    2 3
    0 1
    6
    1 5
    1 3
    3 5
    2 10
    11 11
    12 12
    0 1 1 0 0 1

    Hint

    样例1: 第一条线段是蓝色,第二条线段是红色。

    两组样例都可能有其他正确答案。

    Source

    2018 UESTC ACM Training for Graph Theory    
    题解:观察发现,仅当一条线段结束或开始时,染色情况才可能有变化。若将所有线段表示为[L,R],则将它们全部延伸至[L,R+1),就无需单独考虑整点。    
    将所有左边界和右边界+1位置的整点去重排序,形成集合 {x1, x2, ..., xk},则只需考虑区间[0, x1) [x1, x2) ... [xk-1, xk) [xk, ∞) 。    [0, x1) [x1, x2) ... [xk-1, xk) [xk, ∞) 
         X1        X2     ...       Xk         Xk+1
    若将一个区间涂色,则所有包含这个区间的线段都要被涂色。
    把这些区间看做图的节点,把线段看做图的边。
    例如:对于一条包含区间{Xi, Xi+1, ..., Xj-1, Xj} 的线段,可以视为点i连向点j+1的一条无向边。这样,就组成了多个连通图。
    对于每个连通图,我们需要把这些边按相同的方法涂色,就能解决问题。
    假设:连通图当中,所有节点的度数都为偶数。

    那么,图中所有边组成的一条路径构成了一条欧拉回路。

    代码:
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6;
    const int maxn1=3e5;
    struct part{
    int v,id;
    } ee[maxn];


    struct part1{
    int to,net;
    } e[maxn];


    int b[maxn],c[maxn],d[maxn],vis[maxn],flag[maxn],cnt,n,k,len;
    int a[maxn],v[maxn],g[maxn1],head[maxn1],st[maxn1],du[maxn1],emp[maxn1],top,s[maxn1],f[maxn1];


    bool cmp(part a,part b)
    {
        return a.v<b.v;
    }


    void addedge(int x,int y)
    {
        v[cnt]=0;
        e[cnt].to=y;
        e[cnt].net=st[x];
        st[x]=cnt++;
    }


    void dfs(int x)
    {
        if(emp[x]==1) return ;
        top++;
        s[top]=x;
        int ii=st[x];
        while (ii!=-1&&v[ii]) ii=e[ii].net;
        st[x]=ii;
        if(ii==-1) 

    emp[x]=1;
    return ; 
    }
        if(ii!=-1)
        {
            v[ii]=1;
            st[x]=e[ii].net;
            if (st[x]==-1) emp[x]=1;
            int p=e[ii].to;
            int jj=ii^1;
            v[jj]=1;
            dfs(p);
        }
    }


    void fluey(int x)
    {
        top=0;
        s[top]=x;
        while(top>=0)
        {
            if (emp[s[top]]==1)
            {
                len+=1;
                f[len]=s[top];
                flag[s[top]]=1;
                top--;
            } 
    else
            {
                top--;
                dfs(s[top+1]);
            }
        }
    }


    int main()
    {
    ios::sync_with_stdio(false);
    cin.tie(0);
        cin>>n;
        int temp=0,x,y;
        for(int i=1;i<=n;i++)
        {
            cin>>x>>y;
            temp+=1;
            ee[temp].v=x;
            ee[temp].id=i;
            temp+=1;
            ee[temp].v=y+1;
            ee[temp].id=i+n;
        }


        sort(ee+1,ee+1+2*n,cmp);
        for(int i=1;i<=2*n;i++) c[ee[i].id]=i;
        d[1]=ee[1].v;
        b[1]=1;
        k=1;
        for(int i=2;i<=2*n;i++) 
        {
        if(ee[i].v==d[k]) { b[i]=k; continue; } 
    else { k++; d[k]=ee[i].v; b[i]=k; }
        
        cnt=0;
        for(int i=1;i<=n*2;i++) st[i]=-1;
        for(int i=1;i<=n;i++)
        {
            addedge(b[c[i]],b[c[i+n]]);
            addedge(b[c[i+n]],b[c[i]]);
            du[b[c[i]]]++;
            du[b[c[i+n]]]++;
            v[i-1]=0;
            v[i+n-1]=0;
        }


        temp=0;
        for(int i=1;i<=2*n;i++)
        if(du[i]&1) a[++temp]=i;   
       
        sort(a+1,a+1+temp);
        for(int i=1;i<=temp;i++)
        if(i & 1)
        {
            addedge(a[i],a[i+1]);
            addedge(a[i+1],a[i]);
            du[a[i]]+=1;
            du[a[i+1]]+=1;
        }
        for(int i=1;i<=n*2;i++)
        {
        if(du[i]>0) emp[i]=0; 
    else emp[i]=1;
    }
            
        for(int i=1;i<=2*n;i++) head[i]=st[i];
        for(int j=1;j<=2*n;j++)
        {
        if(!flag[j] && du[j]>0)
        {
          len=0;
          fluey(j);
          memset(vis,0,sizeof vis);
          for(int i=1;i<=len-1;i++)
          {
            x=f[i]; y=f[i+1];
            int ii=head[x];
            while(ii!=-1)
            {
                if(e[ii].to==y && vis[ii]==0) break;
                ii=e[ii].net;
            }
            if(x<y) g[ii/2+1]=1; 
    else g[ii/2+1]=0;
            vis[ii]=1;
            vis[ii^1]=1;
          }
        }
    }
        for(int i=1;i<=n;i++) i==n? cout<<g[i]<<endl : cout<<g[i]<<" ";
        return 0;
    }











  • 相关阅读:
    ☀【CSS3】形状
    ♫【MV*】
    ☀【布局】多栏布局 / 盒布局
    2017 无奈的模拟赛 1
    洛谷——P2093 零件分组
    洛谷——P1209 [USACO1.3]修理牛棚 Barn Repair
    洛谷——P2695 骑士的工作
    洛谷——P1330 封锁阳光大学
    python(16)- python内置函数
    MTK平台缩写
  • 原文地址:https://www.cnblogs.com/csushl/p/9386527.html
Copyright © 2011-2022 走看看