思路:tarjan找桥+并查集维护,将所有桥两端的点合并,然后将任意一个集合标黑,其他所有集合标白
然后#14 TLE了
复杂度应该是 O(n+m⋅α(n)) ,为什么会被卡呢
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int t,n,m,x,y,fa[200050],have_ans,f[200050],siz[200050];
int dfn[200050],low[200050],nth;
bool flag[200050],bridge[200050];
vector<int> T[200050];
inline int read(){
int n=0,f=1;
char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0' && c<='9'){
n=(n<<3)+(n<<1)+(c^48);
c=getchar();
}
return n*f;
}
void pre_dfs(int no){
flag[no]=1;
++have_ans;
for(unsigned i=0;i<T[no].size();i++){
if(flag[T[no][i]]==0){
fa[T[no][i]]=no;
pre_dfs(T[no][i]);
}
}
}
void dfs(int no,int lst){
dfn[no]=low[no]=++nth;
for(unsigned i=0;i<T[no].size();i++){
if(dfn[T[no][i]]==0){
dfs(T[no][i],no);
low[no]=min(low[no],low[T[no][i]]);
bridge[T[no][i]]=(low[T[no][i]]>dfn[no]);
}else if(T[no][i]!=lst)low[no]=min(low[no],dfn[T[no][i]]);
}
}
int find(int x){
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
void merge(int x,int y){
int tmp1=find(x),tmp2=find(y);
if(tmp1==tmp2)return;
if(siz[tmp1]>siz[tmp2])swap(tmp1,tmp2);
f[tmp1]=tmp2;
siz[tmp2]+=siz[tmp1];
}
int main()
{
t=read();
while(t--){
n=read();m=read();
for(int i=1;i<=n;i++)T[i].clear();
for(int i=1;i<=m;i++){
x=read();y=read();
T[x].push_back(y);
T[y].push_back(x);
}
memset(flag,0,sizeof(flag));
have_ans=0;
pre_dfs(1);
if(have_ans!=n){
puts("-1");
continue;
}
memset(dfn,0,sizeof(dfn));
nth=0;
dfs(1,0);
for(int i=1;i<=n;i++)f[i]=i,siz[i]=1;
for(int i=1;i<=n;i++)
if(bridge[i])merge(i,fa[i]);
have_ans=0;
for(int i=2;i<=n;i++)
if(find(i)!=find(1))have_ans=1;
if(have_ans==0){
puts("-1");
continue;
}
for(int i=1;i<=n;i++)
putchar(find(i)==find(1)?'B':'W');
puts("");
}
return 0;
}