CS 400 Simple Pahts 割边,路径唯一

本文介绍了一种利用图论中的割边概念来判断两点间是否存在唯一简单路径的方法。通过遍历图并标记割边,仅保留这些边形成新图,若两节点仍连通则表明路径唯一。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:n点m条边的无向图,Q次询问,每次询问(x,y) 问x->y的简单路径是否唯一? n,m,Q<=1e3.


现在找到一条x-y的路径p. 那么路径p上的边 如果存在有一条边不是割边的话 那么x-y有多条路径 (因为去掉这条边后 x->y仍然有路径).
如果路径p上的边都为割边 那么x->y存在唯一一条路径 (假如还有路径 那么代表p上的某条边去掉后 x-y仍然联通,矛盾.)


现在只保留图中的割边 如果此时x-y还是联通 那么x-y只有一条简单路径.

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
struct node{
	int u,v,nxt;
}e[N];
int head[N],lo[N],dn[N],bri[N];
int cnt=0,num=0,n,m,Q,tot=0;
void add_edge(int u,int v)
{
	e[cnt].u=u,e[cnt].v=v;
	e[cnt].nxt=head[u],head[u]=cnt++;
}
void dfs(int u,int fa)
{
	lo[u]=dn[u]=++tot;
	for(int i=head[u];i!=-1;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==fa)
			continue;
		if(!dn[v])
		{
			dfs(v,u);
			lo[u]=min(lo[u],lo[v]);
			if(lo[v]>dn[u])
				bri[++num]=i;
		}
		else
			lo[u]=min(lo[u],dn[v]);
	}
}
int fa[N],u,v;
int find(int x)
{
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main()
{
	cin>>n>>m>>Q;
	memset(head,-1,sizeof(head));
	for(int i=1;i<=n;i++)
		fa[i]=i,dn[i]=0;
	for(int i=0;i<m;i++)
	{
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs(1,0);
//	cout<<"tsubasa "<<num<<endl;
	for(int i=1;i<=num;i++)
	{
		int fx=find(e[bri[i]].u),fy=find(e[bri[i]].v);
		if(fx!=fy)
			fa[fx]=fy;
	}
	while(Q--)
	{
		scanf("%d%d",&u,&v);
		puts((find(u)==find(v))?"1":"0");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值