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

CodeForces - 817F Graph and String(dfs判二分图)

程序员文章站 2022-07-05 09:33:34
题目链接:点击查看题目大意:给出一张图,现在要求给出一种合适的染色方案,使得:只能用 ' a ' , ' b ' , ' c ' 进行染色有边相连的两个点的颜色要么相同,要么相邻,不能是 ' a ' 和 ' c '没有边相连的两个点的颜色只能是 ' a ' 和 ' c '题目分析:基于第三个条件,不难看出原图的补图如果不是一个二分图时,答案一定是 No,因为无法处理所有情况三而当原图的补图是一个二分图时,相当于只满足一个必要条件,还需要判断一下情况二作为充分条件才行,只有同时满足了情况...

题目链接:点击查看

题目大意:给出一张图,现在要求给出一种合适的染色方案,使得:

  1. 只能用 ' a ' , ' b ' , ' c ' 进行染色
  2. 有边相连的两个点的颜色要么相同,要么相邻,不能是 ' a ' 和 ' c '
  3. 没有边相连的两个点的颜色只能是 ' a ' 和 ' c '

题目分析:基于第三个条件,不难看出原图的补图如果不是一个二分图时,答案一定是 No,因为无法处理所有情况三

而当原图的补图是一个二分图时,相当于只满足一个必要条件,还需要判断一下情况二作为充分条件才行,只有同时满足了情况二和情况三才能说明本题是有解的

然后就是一个小坑,这个题目中的原图和补图都不一定是一张连通图,所以需要当多个连通图依次处理才行

代码:
 

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;
     
typedef long long LL;
     
typedef unsigned long long ull;
     
const int inf=0x3f3f3f3f;

const int N=510;

bool maze[N][N];

vector<int>node[N];

int c[N],n,m;

char ans[N];

bool vis[N];

bool dfs(int u,int val)//二分图染色
{
	c[u]=val;
	for(auto v:node[u])
	{
		if(c[v]!=-1)
		{
			if(c[u]==c[v])
				return false;
			continue;
		}
		if(!dfs(v,val^1))
			return false;
	}
	return true;
}

bool check(int u)//判断情况二
{
	vis[u]=true;
	for(int i=1;i<=n;i++)
		if(maze[u][i])
		{
			if(abs(ans[u]-ans[i])>1)
				return false;
			if(!vis[i]&&!check(i))
				return false;
		}
	return true;
}

int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
	memset(c,-1,sizeof(c));
	int rt=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		maze[u][v]=maze[v][u]=true;
	}
	for(int i=1;i<=n;i++)	
		for(int j=i+1;j<=n;j++)
			if(!maze[i][j])
			{
				node[i].push_back(j);
				node[j].push_back(i);
			}
	bool flag=true;
	for(int i=1;i<=n;i++)//对所有的连通块进行二分图染色,判断情况三
		if(c[i]==-1&&node[i].size())
			flag&=dfs(i,0);
	if(flag)
	{
		for(int i=1;i<=n;i++)
		{
			if(c[i]==1)
				ans[i]='a';
			else if(c[i]==0)
				ans[i]='c';
			else
				ans[i]='b';
		}
		bool flag=true;
		for(int i=1;i<=n;i++)//对所有的连通块判断情况二
			flag&=check(1);
		if(flag)//同时满足才是YES
		{
			puts("Yes");
			for(int i=1;i<=n;i++)
				putchar(ans[i]);
			puts("");
		}
		else
			puts("No");
	}
	else
		puts("No");




















    return 0;
}

 

本文地址:https://blog.csdn.net/qq_45458915/article/details/110206716

相关标签: dfs 图论 构造