CodeForces - 817F Graph and String(dfs判二分图)
程序员文章站
2022-07-05 09:33:34
题目链接:点击查看题目大意:给出一张图,现在要求给出一种合适的染色方案,使得:只能用 ' a ' , ' b ' , ' c ' 进行染色有边相连的两个点的颜色要么相同,要么相邻,不能是 ' a ' 和 ' c '没有边相连的两个点的颜色只能是 ' a ' 和 ' c '题目分析:基于第三个条件,不难看出原图的补图如果不是一个二分图时,答案一定是 No,因为无法处理所有情况三而当原图的补图是一个二分图时,相当于只满足一个必要条件,还需要判断一下情况二作为充分条件才行,只有同时满足了情况...
题目链接:点击查看
题目大意:给出一张图,现在要求给出一种合适的染色方案,使得:
- 只能用 ' a ' , ' b ' , ' c ' 进行染色
- 有边相连的两个点的颜色要么相同,要么相邻,不能是 ' a ' 和 ' c '
- 没有边相连的两个点的颜色只能是 ' 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
上一篇: generate signed Bundle apk点击编译apk无反应
下一篇: ADB的常用命令