题面:https://www.luogu.org/problem/P5058
本题为我们提供了一个很好的思路:若存在u,v,满足dfn[v]<=dfn[u]则v一定在以u为根的子树内,然后这题就变成了找割点的题目. Code: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<ctime> #include<queue> using namespace std; const int N=200005; int n,c1,c2,head[N],cnt,dfn[N],low[N],tim; bool cur[N]; struct Node{ int u,v,nxt; }edge[N*2]; void add(int u,int v){ ++cnt; edge[cnt].u=u; edge[cnt].v=v; edge[cnt].nxt=head[u]; head[u]=cnt; } void tarjan(int u,int fa){ dfn[u]=low[u]=++tim; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].v; if(v!=fa){ if(dfn[v]==-1){ tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]&&u!=c1&&dfn[v]<=dfn[c2]){ cur[u]=1; } } low[u]=min(low[u],dfn[v]); } } } int main(){ int u,v; memset(dfn,-1,sizeof(dfn)); scanf("%d",&n); while(~scanf("%d%d",&u,&v)){ if(u==0&&v==0){ break; } add(u,v); add(v,u); } scanf("%d%d",&c1,&c2); tarjan(c1,0); for(int i=1;i<=n;i++){ if(cur[i]){ printf("%d\n",i); return 0; } } puts("No solution"); return 0; }