題目鏈接:51NOD - 1677treecnt
顯然可以考慮每條邊的貢獻。
假設這條邊左邊s個點,右邊n-s個點。只有左右都有點,那麼這條邊就會貢獻答案。然後容斥計算就是總方案減去全在左邊或者全在右邊。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+7;
int n,k,sz[N],fac[N]={1},res;
vector<int> g[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
inline int qmi(int a,int b=mod-2){
int res=1;
while(b){if(b&1LL) res=res*a%mod; a=a*a%mod; b>>=1LL;}
return res;
}
inline int C(int n,int m){
if(m>n) return 0;
return fac[n]*qmi(fac[m])%mod*qmi(fac[n-m])%mod;
}
void dfs(int x,int fa){
sz[x]=1;
for(auto to:g[x]) if(to!=fa){
dfs(to,x); int s=sz[to];
res=(res+(C(n,k)-C(n-s,k)-C(s,k))%mod+mod)%mod;
sz[x]+=sz[to];
}
}
signed main(){
cin>>n>>k;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
for(int i=1,a,b;i<n;i++) scanf("%lld %lld",&a,&b),add(a,b);
dfs(1,1); cout<<res;
return 0;
}