[欧拉回路] Codeforces 429E #245 (Div. 1) E. Points and Segments

CodeForces 博客算法解析
本文提供了一个具体的算法实现案例,通过使用快速读入、邻接表、深度优先搜索等技术解决了一类图论问题。该算法还涉及了二分查找、内存优化等技巧,确保了程序在大规模数据输入下的高效运行。

题解传送门:http://codeforces.com/blog/entry/12265


#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
  return *p1++;
}

inline void read(int &x){
  char c=nc(),b=1;
  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

const int N=200005;

struct edge{
  int u,v,next;
}G[N<<2];
int head[N],inum=1;

inline void add(int u,int v,int p){
  G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}

int deg[N];
int dir[N<<2],vst[N];
#define V G[p].v
inline void dfs(int u){
  vst[u]=1;
  for (int p=head[u];p;p=G[p].next)
    if (dir[p>>1]==-1){
      dir[p>>1]=p&1;
      dfs(V);
    }
}

int sx[N],icnt;
inline int Bin(int x){
  return lower_bound(sx+1,sx+icnt+1,x)-sx;
}

int n,root;
int s[N],t[N];

int main(){
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  read(n);
  for (int i=1;i<=n;i++)
    read(s[i]),read(t[i]),t[i]++,sx[++icnt]=s[i],sx[++icnt]=t[i];
  sort(sx+1,sx+icnt+1);
  icnt=unique(sx+1,sx+icnt+1)-sx-1;
  for (int i=1;i<=n;i++){
    s[i]=Bin(s[i]),t[i]=Bin(t[i]);
    add(s[i],t[i],++inum); add(t[i],s[i],++inum);
    deg[s[i]]++; deg[t[i]]++;
  }
  int last=0;
  for (int i=1;i<=icnt;i++)
    if (deg[i]&1){
      if (last)
	add(last,i,++inum),add(i,last,++inum),last=0;
      else
	last=i;
    }
  for (int i=1;i<=(inum>>1);i++) dir[i]=-1;
  for (int i=1;i<=icnt;i++)
    if (!vst[i])
      dfs(i);
  for (int i=1;i<=n;i++)
    printf("%d ",dir[i]^1);
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值