【JZOJ4822】完美标号

来源:互联网 发布:h5 banner轮播js源码 编辑:程序博客网 时间:2024/06/06 03:01

Description

给定M个二元组(A_i, B_i),求X_1, …, X_N满足:对于任意(A_i, B_i),有|X_{A_i} - X_{B_i}| = 1成立。

Solution

一种可行方案,一定是有只填0或1的方法,于是我们给二元组连边,然后直接染色,发现冲突直接输出NO。

为什么不填两种以上的数?

我们假设有一条链,然后我们要随机往上面加边,那么如果有两种以上的数,就会有相差大于1的情况,那么我们不如直接填两种数取尽量多的满足相差为1的情况。

Code

#include<iostream>#include<cstdio>#include<cstdlib>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 10001#define M 200001using namespace std;int to[M],next[M],last[M],num=0;int c[N];void link(int x,int y){    num++;    to[num]=y;    next[num]=last[x];    last[x]=num;}void dfs(int x,int t){    c[x]=t;    for(int i=last[x];i;i=next[i])    {        int v=to[i];        if(c[v]==-1) dfs(v,1-t);        else if(c[v]==t)        {            printf("NO");            exit(0);        }    }}int main(){    freopen("perfect.in","r",stdin);    freopen("perfect.out","w",stdout);    int n,m;    cin>>n>>m;    fo(i,1,m)    {        int x,y;        scanf("%d %d",&x,&y);        link(x,y);        link(y,x);    }    fo(i,1,n) c[i]=-1;    fo(i,1,n)    if(c[i]==-1) dfs(i,0);    printf("YES\n");    fo(i,1,n) printf("%d ",c[i]);}
1 0
原创粉丝点击