如何证明或证伪此方法正确性?
查看原帖
如何证明或证伪此方法正确性?
572133
潘德理2010楼主2023/11/19 09:57

看了看题解,不太明白,于是口胡想出了下面的做法,得到 AC。

先把所有的不在任何一条 aa 到 bb 的简单路径上的点筛出来,扔掉,然后直接求割点。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,a,b,fi[200010],vis[200010],ans=1e9;
int l[200010],d[200010],s[200010],ct[200010],c,r;
vector<int> e[200010],k[200010];
void dfs(int u){
	if(u==b) return ;
	vis[u]=1;
	for(int i=0;i<int(e[u].size());i++){
		int v=e[u][i];
		if(!vis[v]){
			dfs(v);
			fi[u]=max(fi[u],fi[v]);
		} 	
	}
}
void tarj(int u){
	l[u]=d[u]=++c;
	int son=0;
	for(int i=0;i<int(k[u].size());i++){
		int v=k[u][i];
		if(!d[v]){
			son++;
			tarj(v);
			l[u]=min(l[u],l[v]);
			if(l[v]>=d[u]&&u!=r) ct[u]=1;
		}
		else l[u]=min(l[u],d[v]);
	}
	if(u==r&&son>=2) ct[u]=1;
}
int main(){
	scanf("%d",&n);
	while(1){
		scanf("%d%d",&a,&b);
		if(a==0&&b==0) break;
		e[a].push_back(b);
		e[b].push_back(a);
	}
	scanf("%d%d",&a,&b);
	fi[b]=1;
	dfs(a);
	for(int i=1;i<=n;i++){
		for(int j=0;j<int(e[i].size());j++){
			int v=e[i][j];
			if(fi[i]==fi[v]&&fi[i]==1) k[i].push_back(v);
		}
	}
	for(int i=1;i<=n;i++){
		if(!d[i]&&fi[i]){
			r=i;
			tarj(i);
		}
	}
	for(int i=1;i<=n;i++){
		if(ct[i]&&i!=a&&i!=b) ans=min(i,ans);
	}
	if(ans==int(1e9)) printf("No solution");
	else printf("%d",ans);
}
2023/11/19 09:57
加载中...