A. Graph and String(hash+暴力构造)

, 首先发现假如两个字母相等,那么他们的边一定完全相等

这是个很重要的结论,这样可以用hash压缩边的状态

, a , b , c , N O 压缩之后,边的状态最多只有a,b,c三种,大于三种直接NO

, 接着,我们就把点按照边集分成了小于等于三个集合

, 暴力枚举每个集合的字母,然后判断是否可行

, \color{Red}代码可能略长,但是思路却非常容易理解

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll base=131;
const int mod=1e5+10;
int n,m,HASH[mod],top,inf,vis[509][509];
char a[509];
int get_hash(int x)
{
	int mo=1,ans=0,temp=0;
	for(int i=1;i<=n;i++) 
	{
		if( vis[x][i] )	ans+=mo;
		mo=mo*base%mod;
		temp=(temp+mo)%mod;
	}
	inf=temp;
	return ans; 
}
bool perfect()
{
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if( i==j )	continue;
		if( abs(a[i]-a[j])<=1&&vis[i][j]==0 )	return false;
		if( abs(a[i]-a[j])>=2&&vis[i][j] )	return false;
	} 
	return true;
}
void run_two(char q,char w)
{
	for(int i=1;i<=n;i++)
		if( HASH[1]==get_hash(i) )	a[i]=q;
		else	a[i]=w;
	if( perfect() )
	{
		cout << "Yes" << endl;
		for(int i=1;i<=n;i++)	cout << a[i];
		exit(0);
	}
}
void run_three(char q,char w,char e)
{
	for(int i=1;i<=n;i++)
		if( HASH[1]==get_hash(i) )	a[i]=q;
		else if( HASH[2]==get_hash(i) )	a[i]=w;
		else	a[i]=e;
	if( perfect() )
	{
		cout << "Yes" << endl;
		for(int i=1;i<=n;i++)	cout << a[i];
		exit(0);
	}	
}
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)	vis[i][i]=1;
	for(int i=1;i<=m;i++)
	{
		int l,r;
		cin >> l >> r;
		vis[l][r]=vis[r][l]=1;
	}
	for(int i=1;i<=n;i++)	
	{
		int sumn=get_hash(i),flag=0;
		for(int j=1;j<=top;j++)
			if( HASH[j]==sumn )	flag=1;
		if( flag==0 )	HASH[++top]=sumn;
	}
	if( top>3 )	cout << "No";
	else
	{
		if( top==1 )
		{
			cout << "Yes\n"; 
			for(int i=1;i<=n;i++)	cout << 'a';
			return 0;
		}
		else if( top==2 )
		{
			for(char i='a';i<='c';i++)
			for(char j='a';j<='c';j++)
			{
				if( i==j )	continue;
				run_two(i,j);
			}
		}
		else
		{
			for(char i='a';i<='c';i++)
			for(char j='a';j<='c';j++)
			for(char q='a';q<='c';q++)
			{
				if( i==j||i==q||j==q )	continue;
				run_three(i,j,q);
			}			
		}
		cout << "No";
	} 
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107665351