Perfect

版权声明:写得不好,随便转载,但请注明出处,感激不尽 https://blog.csdn.net/xyc1719/article/details/83474812

【一句话题意】给定M个二元组(A_i, B_i),求X_1, …, X_N满足:对于任意(A_i, B_i),有|X_{A_i} - X_{B_i}| = 1成立。
【分析】经过不严格的证明我们可以猜想只有不成环或者成偶环时,答案才成立。(一直在0点和1点放一定是最优的)所以只要二分图染色判奇环就可以了,如果是二分图就直接输出染色结果就可以了(反正有spj啦啦啦)。
【code】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxm=1e5+1000;
const int maxn=1e4+1000;
struct Edge{
	int v,nxt;
}edge[maxm<<1];
int head[maxn],tot;
int n,m;
inline void read(int &x){
	x=0;char tmp=getchar();
	while(tmp<'0'||tmp>'9') tmp=getchar();
	while(tmp>='0'&&tmp<='9') x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
}
inline void add_edge(int x,int y){
	edge[tot].v=y;
	edge[tot].nxt=head[x];
	head[x]=tot++;
}
int clr[maxn];
bool dfs(int u){
	for(int i=head[u];i!=-1;i=edge[i].nxt){
		int v=edge[i].v;
		if(clr[v]==-1){clr[v]=clr[u]^1;if(!dfs(v))return false;}
		else if(clr[v]!=clr[u]^1) return false;
	}
	return true;
}
int main(){
	freopen("perfect.in","r",stdin);
	freopen("perfect.out","w",stdout);
	memset(head,-1,sizeof(head));
	memset(clr,-1,sizeof(clr));
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;read(u),read(v);
		add_edge(u,v),add_edge(v,u);
	}
//	printf("NO\n");
	for(int i=1;i<=n;i++)
		if(clr[i]==-1){
			clr[i]=0;
			if(!dfs(i)){printf("NO\n");return 0;}
		}
	printf("YES\n");
	for(int i=1;i<=n;i++)
		printf("%d%c",clr[i],i==n?'\n':' ');
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xyc1719/article/details/83474812