要将答案看做是小问题的贡献和

Description

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

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

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

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

 

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

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

Input

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

Output

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

Input示例

3 2
1 2
1 3

Output示例

4

题目分析

初看上去好像要结合树形结构做一些麻烦的事情……例如判断树中长度为k的连通块个数之类的。

但是实际上问题可以看做是每一条边对于答案贡献了$si$,答案就是$\sum{si}$。

那么单独的贡献自然应该是选择了横跨这条边的两个点的情况。

这里就考虑一下问题的反面:选择了不横跨这条边的情况,应该是$C_{u_{size}}^{k}+C_{v_{size}}^{k}$,其中$u_{size}$和$v_{size}$分别表示这条边两边有多少个点。

于是就愉快地解决这题了。

 #include<bits/stdc++.h>
typedef long long ll;
const ll MO = ;
const int maxn = ;
const int maxm = ; ll fac[maxn],facinv[maxn],ans,sum;
int n,k;
int size[maxn];
int edges[maxm],nxt[maxm],head[maxn],edgeTot; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs1(int x, int fa)
{
size[x] = ;
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=fa) dfs1(edges[i], x), size[x] += size[edges[i]];
}
ll c(ll n, ll m){return n < m?:fac[n]*facinv[n-m]%MO*facinv[m]%MO;}
void dfs2(int x, int fa)
{
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (fa==v) continue;
ans = (ans+sum-c(size[v], k)-c(n-size[v], k))%MO;
dfs2(v, x);
}
}
int main()
{
memset(head, -, sizeof head);
n = read(), k = read(), fac[] = facinv[] = facinv[] = ;
for (int i=; i<n; i++) addedge(read(), read());
for (int i=; i<=n; i++) facinv[i] = (MO-MO/i)*facinv[MO%i]%MO;
for (int i=; i<=n; i++)
fac[i] = (fac[i-]*i)%MO, facinv[i] = facinv[i]*facinv[i-]%MO;
sum = c(n, k);
dfs1(, );
dfs2(, );
printf("%lld\n",(ans+MO)%MO);
return ;
}

END

最新文章

  1. Android Studio 个人常用设置
  2. HTML5之创新的视频拼图剖析式学习之二
  3. MySQL创建复合索引
  4. [DevExpress]设置RepositoryItemComboBox只可下拉选择不可编辑
  5. background image position问题
  6. delphi中左右翻转窗体(修改EXStyle)
  7. D7升级时候发现许多System函数和网络函数只有Byte版本的,需要注意
  8. django+celery+rabitmq
  9. 转:LoadRunner中参数化技术详解
  10. linux ip 转发设置 ip_forward
  11. 分针网—每日分享:HTML解析原理
  12. GreenDao 使用二
  13. ConcurrentModificationException异常出现的原因
  14. Access-Control-Allow-Origin设置跨域
  15. easyui中datagrid+layout布局
  16. 神州数码策略路由(PBR)配置
  17. redis 缓存锁的实现方法
  18. Windows开启远程桌面服务(Win10)
  19. MySQL数据库的学习
  20. 在PE32位下安装64位2003、2008系统

热门文章

  1. 【UVA - 156 】Ananagrams (set,map,vector)
  2. Linux | C代码的编写、运行和调试
  3. AKOJ-2021-逆序对(归并,二分)
  4. 16 Groovy 和并发
  5. 17995 Stupid thief 组合数学
  6. js去掉字符串前后以及中间的空格
  7. session 跟 cookie 关系
  8. vue2.0:(一)、vue的安装和项目搭建(以外卖app项目举例)
  9. arcgis jsapi接口入门系列(3):各种类型的图层添加
  10. GreenDao3.2的使用