D1. LuoTianyi and the Floating Islands
题意:给定一颗树,有k个点随机分布在树上,定义good点为到k个点距离和最小的点。求good点数量的期望。
思路:当k=奇数时时,当点移动,到每个点的距离都改加1或减1。因为是奇数,所以不存在总改变量为0的情况,因此good点有且只有一个。综上所述,只需要考虑k=2的情况。对于两点来说,两点连线上的点均为good点。即可转化为求树上所有结点到其余结点的距离和,经典换根dp.
//换根dp
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
using namespace std;
#define PII pair<int,int>
#define V vector<int>
#define endl "\n"
#define int long long
typedef long long LL;
typedef unsigned long long ULL;
const int N=2e5+10,M=2*N;
const int mod=1e9+7;
int n,k;
int dist[N],sz[N],dp[N];
int h[N],e[M],ne[M],idx;
void add(int a,int b) {
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs1(int u,int fa) {
sz[u]=1;
for(int i=h[u];~i;i=ne[i]) {
int v=e[i];
if(v==fa) continue;
dfs1(v,u);
dp[u]+=dp[v]+sz[v];
sz[u]+=sz[v];
}
}
void dfs2(int u,int fa) {
for(int i=h[u];~i;i=ne[i]) {
int v=e[i];
if(v==fa) continue;
dist[v]=dist[u]+n-2*sz[v];
dfs2(v,u);
}
}
int qpow(int a,int b) {
int res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
void solve() {
cin>>n>>k;
if(k&1) {
cout<<1<<endl;
return ;
}
memset(h,-1,sizeof h);
for(int i=1;i<n;i++) {
int a,b;
cin>>a>>b;
add(a,b),add(b,a);
}
dfs1(1,0);
dist[1]=dp[1];
dfs2(1,0);
int res=0;
for(int i=1;i<=n;i++) res=(res+dist[i]);
res=res+(LL)n*(n-1)%mod;
res=res%mod*qpow(n,mod-2)%mod*qpow(n-1,mod-2)%mod;
cout<<res;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
solve();
return 0;
}