被卡一个点求助
查看原帖
被卡一个点求助
241838
microchip楼主2024/9/8 19:42

思路:tarjan找桥+并查集维护,将所有桥两端的点合并,然后将任意一个集合标黑,其他所有集合标白

然后#14 TLE了

复杂度应该是 O(n+m⋅α(n))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;
}

2024/9/8 19:42
加载中...