• 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;
    }
    
  • 相关阅读:
    uva 1511 最小生成树
    百度之星2017初赛A-1006-度度熊的01世界
    工作5年总结-总结这两年在阳光的日子
    在visual studio中查看源代码
    根据C#编程经验思考编程核心
    项目的可维护可持续性思考
    java学习
    What is ASP.NET SignalR
    WCF 和 ASP.NET Web API
    wcf服务
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8486387.html
Copyright © 2020-2023  润新知