51nod 1677——treecnt
题意:给你n个结点,n-1条边,要从这n个结点里面选出k个结点,再选出最少边使这些结点之间相互连通,问对于所有选择k个结点的最小选择边数的总和是多少。
题解:因为每次选k个点其实是固定了的,所以撇开要确定的边,每次要选的k个点就是一个组合数问题,那怎么把点和边联系起来呢?对于任意一条边,它要不要被选入作为连接点的边是由它两边的点决定的。当只有这条边左边或者右边的点被选入时,这条边是不需要的,只有当两端的两个点同时被选入,这条边才会对答案有贡献。
而判断这条边两端的点被选入的情况时,只用分三种情况:
① 在这条边左边选了k个点,这条边不计入答案,无贡献。
② 在这条边右边选了k个点,这条边不计入答案,无贡献。
③ 在这条边两端都选了点,这条边必然记入答案,贡献加1。
所以根据上面的情况我们容易得到 对于每一条边它的贡献是:ans=C(n,k)-C(t,k)-C(n-t,k),这里的t就是该边左边的结点数。已经知道这个式子了,我们只需要统计每条边左边和右边的结点总数,然后依次带入式子把答案求出来就行了。由于题目要求取模,阶乘的数又比较大所以要用到阶乘逆元(套个阶乘逆元的板子就行了)。
附上代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=1000010;
ll fac[maxn]; //阶乘
ll inv[maxn];//阶乘的逆元
ll n,k,ans,ss;
vector<ll>q[maxn];
ll qpow(ll x,ll n)
{
ll ret=1;
for(; n; n>>=1)
{
if(n&1)
ret=ret*x%mod;
x=x*x%mod;
}
return ret;
}
void getjni()
{
fac[1]=1;
for(int i=2; i<=maxn; i++)//预处理阶乘
fac[i]=fac[i-1]*i%mod;
inv[maxn]=qpow(fac[maxn],mod-2);//求阶乘的逆元
for(int i=maxn-1; i>=0; i--)
inv[i]=inv[i+1]*(i+1)%mod;
}
ll C(ll a,ll b)
{
if(b>a)
return 0;
if(b==0)
return 1;
return fac[a]*inv[b]%mod*inv[a-b]%mod;//计算组合数
}
ll dfs(int st,int en)
{
ll cnt=1;
for(int i=0; i<q[st].size(); i++)
{
if(q[st][i]==en) continue;
ll t=dfs(q[st][i],st);//找左边有多少个结点
cnt+=t;
ans=(ans+ss-C(t,k)-C(n-t,k))%mod;
}
return cnt;
}
int main()
{
getjni();
while(scanf("%lld%lld",&n,&k)!=EOF)
{
ans=0;
ss=C(n,k);
for(int i=1; i<=n; i++)
q[i].clear();
for(int i=1; i<n; i++)
{
ll u,v;
scanf("%lld%lld",&u,&v);
q[u].push_back(v);
q[v].push_back(u);
}
dfs(1,-1);
printf("%lld\n",(ans+mod)%mod);
}
}
51nod 1677——treecnt相关推荐
- 51Nod 1677 treecnt
容斥 按照套路,按边考虑.一条边能贡献的答案是选的k个点分居两侧的方案数.发现这东西很难求.于是转成容斥求k个点归于一侧的方案数. #include<cstdio> #define N 1 ...
- 1677 treecnt(贡献)
1677 treecnt 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给定一棵n个节点的树,从1到n标号.选择k个点,你需要选择一些边使得这k个点通过选择的边联 ...
- treecnt 51Nod - 1677
给定一棵n个节点的树,从1到n标号.选择k个点,你需要选择一些边使得这k个点通过选择的边联通,目标是使得选择的边数最少. 现需要计算对于所有选择k个点的情况最小选择边数的总和为多少. 样例解释: 一共 ...
- 51nod 1617 奇偶数组
传送门 回来看一眼51nod,发现自己掉到rank4了,赶紧切道题回rank3. 一眼不会做,这种东西应该慢慢找规律吧--然后看到数据范围其实比较小,应该是单次log的,那是不是可以分治啊. #inc ...
- 1677: [Usaco2005 Jan]Sumsets 求和
1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 626 Solved: 348 [Sub ...
- 51NOD 1773:A国的贸易——题解
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1773 参考1:FWT讲解 https://www.cnblogs.com ...
- 51nod 1040:最大公约数之和(数论)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040 给出一个n,求1-n这n个数,同n的最大公约数的和. ...
- (DP)51NOD 1183 编辑距离
编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除 ...
- 斜率小于0的连线数量 51Nod - 1107 (树状数组+离散化)
二维平面上N个点之间共有C(n,2)条连线.求这C(n,2)条线中斜率小于0的线的数量. 二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y).例如:(2,3) (3,4) (1,5) (4, ...
最新文章
- 利用硅光子学的移动心脏监护仪
- [置顶] ros的navigation之———gmapping应用详解(in ros)
- JSON转换和毫秒时间
- (转)Windows重启延迟删除,重命名技术原理
- 从Google Wave和XML看软件复杂性之争,互联网营销
- 手机号正则_这20个正则表达式,对你有大帮助,快来Make
- asp.net ajax1.0基础回顾(五):调用ASMX(WebService)
- 简单聊聊C#中lock关键字
- 学习C/C++:伴随我成长的编程书!
- Closure 代表匿名函数的类
- Linux分卷压缩zip文件命令,linux下的几种分卷压缩命令
- charles——教程——转载
- 后台获取用户登录信息
- 喝杯水都能泄露指纹?屏下指纹识别设备被攻破
- C#在一个form中改变另一个form中控件的内容、C#做登录界面并且密码显示为*
- oracle物理文件删除如何恢复,Oracle数据文件物理删除后的恢复
- 前端超出文字显示省略号
- 市面上的计算机培训机构 哪家实力最强
- 北京兄弟连web前端
- 解决Graphviz无法显示决策树中文问题