传送门
https://www.luogu.org/problemnew/show/CF547D
重点!!!!!!!!!!!!
- dfs过程中,遍历时必须要加取地址符号,这样可以实时的删去
边表里的边,防止多次访问超时(有vis数组也不行,因为还会进到循环里判断)!!!!
思路
- 点(x,y)可以转化为点x和点y连一条边,这样now边(x,y)表示past点,now点表示past一横行或一竖列
- 这要保证连入now点的边中黑-白<=1即可
- 虚点
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct edge{
int to,next,ind;
}ed[10000010];
int color[10000010],head[10000010],
sz,x[5000010],y[5000010],sum[2000000],
vis[10000010],nn,n,b[10000010],cnt,
du[10000010],cnt1;
const int ss=0;
void add_edge(int from,int to,int ind)
{
ed[++cnt1].to=to;
ed[cnt1].next=head[from];
ed[cnt1].ind=ind;
head[from]=cnt1;
}
int read()
{
int x=0,flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar(); }
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x*flag;
}
void dfs(int u)
{
for(int &i=head[u];i;i=ed[i].next)
{
int v=ed[i].to,ind=ed[i].ind;
if(vis[ind]) continue;
if(v>nn) color[ind]=1;
else color[ind]=0;
vis[ind]=1;
dfs(v);
}
}
int main()
{
//freopen("color.in","r",stdin);
//freopen("color.out","w",stdout);
scanf("%d",&n);
nn=2*n;
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),b[++cnt]=x[i],b[++cnt]=y[i];
sort(b+1,b+cnt+1);
int sz=unique(b+1,b+cnt+1)-b-1;
for(int i=1;i<=n;i++)
{
x[i]=lower_bound(b+1,b+sz+1,x[i])-b;
y[i]=lower_bound(b+1,b+sz+1,y[i])-b;
}
for(int i=1;i<=n;i++)
{
add_edge(x[i],y[i]+nn,i);
add_edge(y[i]+nn,x[i],i);
du[x[i]]++;
du[y[i]+nn]++;
}
int tot=n;
for(int i=1;i<=n;i++)
{
if(du[x[i]]&1) tot++,add_edge(x[i],ss,tot),add_edge(ss,x[i],tot),du[x[i]]++;
if(du[y[i]+nn]&1) tot++,add_edge(y[i]+nn,ss,tot),add_edge(ss,y[i]+nn,tot),du[y[i]+nn]++;
}
for(int i=1;i<=2000000;i++) dfs(i);
for(int i=1;i<=n;i++) cout<<color[i]<<' ';
return 0;
}
另一种做法
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
const int N=2e5+100;
const int M=2e6+100;
struct node
{
int x,y,num;
}a[N];
struct Edge
{
int v,nxt;
}edge[M];
int head[N],cnt;
void add(int v,int u)
{
cnt++;
edge[cnt].v=v;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
bool cmp1(node a,node b)
{
return a.x<b.x;
}
bool cmp2(node a,node b)
{
return a.y<b.y;
}
int in[N];
int color[N];
bool vis[N];
void dfs(int u,int c)
{
color[u]=c;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].v;
if(!vis[v])
{
vis[v]=true;
dfs(v,c^1);
}
}
}
int main()
{
//freopen("color.in","r",stdin);
//freopen("color.out","w",stdout);
int n;
scanf("%d",&n);
int i,j;
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].num=i;
}
sort(a+1,a+1+n,cmp1);
for(i=1;i<n;i++)
{
if(a[i].x==a[i+1].x)
{
add(a[i].num,a[i+1].num);
add(a[i+1].num,a[i].num);
in[a[i].num]++;in[a[i+1].num]++;
i++;
}
}
sort(a+1,a+1+n,cmp2);
for(i=1;i<n;i++)
{
if(a[i].y==a[i+1].y)
{
add(a[i].num,a[i+1].num);
add(a[i+1].num,a[i].num);
in[a[i].num]++;in[a[i+1].num]++;
i++;
}
}
for(i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=true;
dfs(i,0);
}
}
for(i=1;i<=n;i++)
{
if(!in[i])
{
cout<<'b';
}
else
{
//cout<<color[i]<<' ';
if(color[i]==1)
{
cout<<'b';
}
else
{
cout<<'r';
}
}
}
cout<<endl;
return 0;
}