51Nod

Discription

给定一棵n个节点的树,从1到n标号。选择k个点,你需要选择一些边使得这k个点通过选择的边联通,目标是使得选择的边数最少。

现需要计算对于所有选择k个点的情况最小选择边数的总和为多少。

样例解释:

 

一共有三种可能:下列配图蓝色点表示选择的点,红色边表示最优方案中的边)

选择点{1,2}:至少要选择第一条边使得1和2联通。

 

选择点{1,3}:至少要选择第二条边使得1和3联通。

 

选择点{2,3}:两条边都要选择才能使2和3联通。

 


Input

第一行两个数n,k1<=k<=n<=100000) 
接下来n-1行,每行两个数x,y描述一条边1<=x,y<=n)

Output

一个数,答案对1,000,000,007取模。

Sample Input

3 2
1 2
1 3

Sample Output

4


直接考虑每条边在选哪些点的时候会被选就行了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100000,ha=1000000007;
int jc[maxn+5],ni[maxn+5],n,m,siz[maxn+5],T,ans;
int hd[maxn+5],ne[maxn*2+5],to[maxn*2+5],num;
inline void addlineint x,int y){ to[++num]=y,ne[num]=hd[x],hd[x]=num;}
inline int addint x,int y){ x+=y; return x>=ha?x-ha:x;}
inline int ksmint x,int y){ int an=1; for;y;y>>=1,x=x*ll)x%ha) ify&1) an=an*ll)x%ha; return an;}
inline int Cint x,int y){ return x<y?0:jc[x]*ll)ni[y]%ha*ll)ni[x-y]%ha;}
inline void init){
	jc[0]=1; forint i=1;i<=maxn;i++) jc[i]=jc[i-1]*ll)i%ha;
	ni[maxn]=ksmjc[maxn],ha-2); forint i=maxn;i;i--) ni[i-1]=ni[i]*ll)i%ha;
}

void dfsint x,int fa){
	siz[x]=1;
	forint i=hd[x];i;i=ne[i]) ifto[i]!=fa) dfsto[i],x),siz[x]+=siz[to[i]];
	iffa) ans=addans,addT,ha-addCsiz[x],m),Cn-siz[x],m))));
}

int main){
	int uu,vv; init);
	scanf"%d%d",&n,&m),T=Cn,m);
	forint i=1;i<n;i++){
		scanf"%d%d",&uu,&vv);
		addlineuu,vv),addlinevv,uu);
	}
	dfs1,0),printf"%d
",ans);
	return 0;
}

  

 

Published by

风君子

独自遨游何稽首 揭天掀地慰生平