论为什么WA第10个点...
查看原帖
论为什么WA第10个点...
142549
hbhz_zcy楼主2022/7/8 11:29

我用的方法和题解不太一样,直接用了一个vis数组,代表是否能从该点访问到终点,并且tarjan从源点开始跑的。判据是这个点存在子节点导致割点形成,并且子该节点能够访问到终点。

//g++ -g b.cpp -o b -std=c++14 -O2 -Wall
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=2e5+10;
int N,M,head[maxn],dfn[maxn],low[maxn],nume=0,Tm=0,ans=maxn,vis[maxn],S,T;
struct node{int to,nxt;}e[maxn<<3];
int qd(){
	int rt=0;char c=getchar();
	while(c<'0'||c>'9')  c=getchar();
	while('0'<=c&&c<='9')  rt=(rt<<3)+(rt<<1)+c-48,c=getchar();
	return rt;
}
void edgen(int from,int to){
	e[++nume].nxt=head[from];
	head[from]=nume;
	e[nume].to=to;
}
void dfs(int fa,int u){
//	printf("dfs %d %d\n",fa,u);
	dfn[u]=low[u]=++Tm;int flag=0;
	if(u==T)  vis[u]=1;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(!dfn[v]){
			dfs(u,v);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]&&vis[v])  flag=1;
		}
		else low[u]=min(low[u],dfn[v]);
		if(v!=fa)  vis[u]|=vis[v];
	}
	if(flag&&u!=S&&u!=T)  ans=min(ans,u);
//	printf("%d:dfn=%d,low=%d flag=%d vis=%d\n",u,dfn[u],low[u],flag,vis[u]);
}
int main(){
//	freopen("in.txt","r",stdin);
	N=qd();
	for(;1;M++){
		int x=qd(),y=qd();
		if(x+y==0)  break;
		edgen(x,y),edgen(y,x);
	}
	S=qd(),T=qd();
	dfs(0,S);
	if(ans==maxn)  printf("No solution\n");
	else printf("%d\n",ans);
	return 0;
}
2022/7/8 11:29
加载中...