tarjan 找桥 15pts 求调
查看原帖
tarjan 找桥 15pts 求调
1285691
yinbe2楼主2024/12/14 14:24

思路是从不被桥连接的点中随便找一个染成白色,剩下的染成黑色

#include<iostream>
using namespace std;
int T;
int head[200005],ver[400005],nxt[400005];
int dfn[200005],low[200005],n,m,tot,num; 
bool bridge[400005];
bool dian[200005];
void add(int x,int y)
{
	tot++;
	ver[tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void tarjan(int x,int in_edge)
{
	num++;
	dfn[x]=num;
	low[x]=num;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=ver[i];
		if(!dfn[y])
		{
			tarjan(y,i);
			low[x]=min(low[x],low[y]);
			if(low[y]>dfn[x])
			{
				bridge[i]=true;
				bridge[i^1]=true;
			}
		}
		else if(i!=(in_edge^1))
			low[x]=min(low[x],dfn[y]);		
	}
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		for(int i=2;i<=tot;i++)
		{
			bridge[i]=false;
			nxt[i]=0;
			ver[i]=0;
		}
		tot=1;
		num=0;
		for(int i=1;i<=n;i++)
		{
			dfn[i]=0;
			low[i]=0;
			head[i]=0;
			dian[i]=false;
		}
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			add(x,y);
			add(y,x);			
		}
		bool flag=true;
		tarjan(1,0);
		for(int i=1;i<=n;i++)
		{
			if(dfn[i]==0)
			{
				flag=false;
				break;
			}
		}				
		if(!flag||m==n-1)
		{
			printf("-1\n");
			continue;
		}
		for(int i=2;i<tot;i+=2)
		{
			if(bridge[i])
			{
				dian[ver[i^1]]=true;
				dian[ver[i]]=true;
			}
		}
		flag=true;
		for(int i=1;i<=n;i++)
		{
			if(!flag||dian[i])printf("B");
			else
			{
				flag=false;
				printf("W");
			}
		}
		printf("\n");
	}
	return 0;
}
2024/12/14 14:24
加载中...