题目链接:https://ac.nowcoder.com/acm/contest/2908/G
以 x 或者 y 结点作为根结点建树求解
用 x 结点建树作为例子:
先dfs标记每个结点的子节点个数,然后找到 y 的离 x 最近的父节点 z ,那么从 对应结点与
对应结点 的任意两点的最短路 必经过 x,y 结点 ,那么
即为不符合方案数。
那么答案即为: .
#include<bits/stdc++.h>
#define sscc ios::sync_with_stdio(false)
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
const int maxn=4e5+10;
struct node{
int to,next;
}edge[maxn<<1];
int tot,head[maxn];
void add( int u,int v )
{
edge[tot]={v,head[u]};
head[u]=tot++;
}
void init()
{
memset(head,-1,sizeof(head));
tot=0;
}
ll siz[maxn],fa[maxn];
void dfs( int u,int f )
{
fa[u]=f;
siz[u]=1;
for( int i=head[u];~i;i=edge[i].next )
{
int v=edge[i].to;
if( v==f ) continue;
dfs(v,u);
siz[u]+=siz[v];
}
}
int main()
{
sscc;
cin.tie(0);cout.tie(0);
int n,x,y;
cin>>n>>x>>y;
init();
for( int i=1;i<n;i++ )
{
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
dfs(x,x);
int k=y,num=siz[y];
for( int i=y;;i=fa[i] )
{
num=siz[i];
if( fa[i]==x ) break;
}
siz[x]-=num;
cout<<(1ll*n*(n-1)-1ll*siz[x]*siz[y])<<endl;
return 0;
}

京公网安备 11010502036488号