欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Perfect

程序员文章站 2022-04-01 14:47:43
...

【一句话题意】给定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;
}
相关标签: 题解