一开始看到它的时候,想都没想直接CV了割点的模板。结果是这样的:
再次读题,发现是只用找u->v路径上的最小割点,改一下就A了
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+7; struct node{ int nxt; int to; }edge[2*maxn]; int head[maxn],cnt,tot; bool check[maxn]; int cut[maxn]; void add(int x,int y){ edge[++cnt].nxt=head[x]; edge[cnt].to=y; head[x]=cnt; } int n,m,x,y; int dfn[maxn],low[maxn],sta[maxn],Time; int a,b; void dfs(int x){ dfn[x]=low[x]=++Time; //int son=0;//统计以x为根的子树个数 for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].to; if(!dfn[v]){ dfs(v); low[x]=min(low[x],low[v]); if(x!=a&&low[v]>=dfn[x]&&dfn[v]<=dfn[b]) check[x]=true;//如果其不是根节点,但是它的孩子能回溯到的最近时间比其大,说明其子必须要经过它,所以去掉他则原图不会联通,所以是割点。还有一个细节就是v的dfn要小于b的dfn,因为点必须在ab之间 } else low[x]=min(low[x],dfn[v]); //这个非常重要,一定要是和他能走到得点的时间做比较,而不能和它们的low比较,否则可能会搜不到割点 } //if(x==fa&&son>=2) check[fa]=true;//如果节点是根节点并且子树大于2,是割点 } int main() { scanf("%d",&n); while(1){ scanf("%d%d",&x,&y); if(x==0&&y==0) break; add(x,y); add(y,x); } scanf("%d%d",&a,&b); dfs(a); for(int i=1;i<=n;i++){ if(check[i]){ printf("%d\n",i); return 0; } } printf("No solution\n"); return 0; }