• Codeforces 429E Points and Segments


    Description

    题面
    题目大意:有 (n) 个区间 ([L_i,R_i]) ,你要给每一个区间染红蓝,使得每一个位置被红色染过的次数与被蓝色染过的次数差的绝对值不大于(1)

    Solution

    如果 (L_i->R_i+1) 连边
    染色就变成了定向,那么一个点要被从左往右和从右往左经过的次数的绝对值之差不超过 (1)
    发现一个环就是符合要求的,那么我们就可以试图找一个欧拉回路
    考虑奇度点的处理:
    我们把相邻的奇度点连起来就可以了
    因为某些有交的区间并没有连边,我们用奇度点之间的边把他们连起来,这样就可以构成欧拉回路了

    然后我们只需要把从左往右的边标为红色,从右往左的边标为蓝色即可

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    int n,in[N],head[N],nxt[N<<1],to[N<<1],num=1,b[N],cnt=0,m;
    int lis[N],tot=0,q[N],top=0,fr[N<<1],id[N<<1];bool vis[N],v[N<<1],ans[N];
    inline void link(int x,int y,int ID){
    	nxt[++num]=head[x];to[num]=y;head[x]=num;fr[num]=x;id[num]=ID;
    }
    struct sub{int x,y;}e[N];
    inline void dfs(int x){
    	vis[x]=1;
    	for(int i=head[x];i;i=nxt[i]){
    		head[x]=nxt[i];
    		if(v[i])continue;
    		v[i^1]=1;dfs(to[i]);q[++top]=i;
    	}
    }
    int main(){
      int x,y;
      scanf("%d",&n);
      for(int i=1;i<=n;i++){
    	  scanf("%d%d",&x,&y);
    	  b[++cnt]=x;b[++cnt]=y+1;
    	  e[i]=(sub){x,y+1};
      }
      sort(b+1,b+cnt+1);m=unique(b+1,b+cnt+1)-b-1;
      for(int i=1;i<=n;i++){
    	  x=e[i].x;y=e[i].y;
    	  x=lower_bound(b+1,b+m+1,x)-b;
    	  y=lower_bound(b+1,b+m+1,y)-b;
    	  link(x,y,i);link(y,x,i);in[x]++;in[y]++;
      }
      for(int i=1;i<=m;i++)if(in[i]&1)lis[++tot]=i;
      for(int i=1;i<=tot;i+=2)link(lis[i],lis[i+1],0),link(lis[i+1],lis[i],0);
      for(int i=1;i<=m;i++)
    	  if(!vis[i])dfs(i);
      while(top){
    	  if(id[q[top]])
    		  ans[id[q[top]]]=(fr[q[top]]<to[q[top]]);
    	  top--;
      }
      for(int i=1;i<=n;i++)printf("%d ",ans[i]);
      return 0;
    }
    
  • 相关阅读:
    CSS Hack技术介绍及常用的Hack技巧集锦
    全面了解TCP/IP到HTTP
    JavaScript异步流程控制的前世今生
    mstOne
    mst总结
    媒体查询基本方法使用
    点击按钮复制到剪贴板
    监听图片src发生改变时的事件
    高德地图获取经纬度
    jQuery抽奖插件 jQueryRotate
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8486387.html
Copyright © 2020-2023  润新知