LAOI-6」Yet Another Graph Coloration Problem 题解
比赛时这题唐了一个小时,写篇题解纪念一下。
首先要求黑白之间至少有
考虑使用类似的套路,我们随便选个点开始搜,得到一棵 dfs 搜索树,那么原图就是这棵树加上若干条返祖边(因为是无向图所以没有横叉边)。
记某条返祖边连接的两个节点中深度较深的节点为
那么此时黑白之间显然有 dfs 树的路径,一条是先走 dfs 树到达返祖边的一端,通过返祖边再走 dfs 树的路径。
因此存在返祖边即有解,无解的情况就是树与不连通图。
有解时的方案构造直接模拟上述过程即可。
#include<bits/stdc++.h>
using namespace std;
int t,n,m,ans,vis[200005],u,v,opt,qwq[200005],sum[200005],low[200005],dfn[200005],d;
vector<int>q[200005];
void inline dfs(int x,int fa){
vis[x]=1;
for(int i=0;i<q[x].size();i++){
if(q[x][i]==fa)continue;
if(vis[q[x][i]]){if(ans==0)ans=1,qwq[x]=1;}
else {dfs(q[x][i],x);}
}
}
void inline dfs2(int x,int y){
vis[x]=1;qwq[x]=max(qwq[x],y);
for(int i=0;i<q[x].size();i++){
if(!vis[q[x][i]])
{dfs2(q[x][i],max(y,qwq[x]));}
}
}
int main(){
cin>>t;
while(t--){
cin>>n>>m;
ans=0;
for(int i=1;i<=n;i++)q[i].clear();
for(int i=1;i<=n;i++)vis[i]=qwq[i]=0,low[i]=1e9;
for(int i=1;i<=m;i++){
cin>>u>>v;
q[u].push_back(v);
q[v].push_back(u);
}d=0;
dfs(1,0);opt=0;
for(int i=1;i<=n;i++)
if(vis[i]==0||ans==0){opt=1;cout<<-1<<"\n";break;}
if(opt)continue;for(int i=1;i<=n;i++)vis[i]=0;dfs2(1,0);
for(int i=1;i<=n;i++)
if(qwq[i])cout<<"B";
else cout<<"W";
cout<<"\n";
}
}