treecnt 算法马拉松20(告别美国大选及卡斯特罗)

treecnt

基准时间限制:1 秒 空间限制:131072 KB

给定一棵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个点必然分布在这条边分隔开的两部分。总情况数等于C(n,k),设其中一部分点数为x,另一部分则为n-x,不合法情况数等于C(x,k)+C(n-x,k);然后要解决的就是咋去找一条边两边点的个数,那么我们以某个点为根dfs找出各个点的子树的度,然后遍历每条边,那么当前两个点,度小的必然为另一个的子树,那么x就找出来了。复杂度O(n);
  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<math.h>
  6 #include<queue>
  7 #include<stdlib.h>
  8 #include<set>
  9 #include<vector>
 10 typedef long long LL;
 11 using namespace std;
 12 typedef struct node
 13 {
 14     int x;
 15     int y;
 16 } ss;
 17 ss ans[100005];
 18 vector<int>vec[100005];
 19 int cnt[100005];
 20 bool flag[100005];
 21 int dfs(int n);
 22 LL N[100005];
 23 const LL mod = 1e9+7;
 24 LL quick(LL n,LL m);
 25 int main(void)
 26 {
 27     int n,k,i;
 28     N[0] = 1;
 29     for(i = 1; i <= 100000; i++)
 30     {
 31         N[i] = N[i-1]*(LL)i%mod;
 32     }
 33     while(scanf("%d %d",&n,&k)!=EOF)
 34     {
 35         // int i;
 36         memset(cnt,0,sizeof(cnt));
 37         memset(flag,0,sizeof(flag));
 38         for(i = 0; i <= n; i++)
 39             vec[i].clear();
 40         for(i = 0; i < n-1; i++)
 41         {
 42             scanf("%d %d",&ans[i].x,&ans[i].y);
 43             vec[ans[i].x].push_back(ans[i].y);
 44             vec[ans[i].y].push_back(ans[i].x);
 45         }
 46         dfs(1);
 47         LL ni = N[n-k]*N[k]%mod;
 48         ni  = quick(ni,mod-2);
 49         LL sum = N[n]*ni%mod;
 50         sum = sum*(n-1)%mod;
 51         for(i = 0; i < n-1; i++)
 52         {
 53             int x = cnt[ans[i].x];
 54             int y = cnt[ans[i].y];
 55             int aa = min(x,y);
 56             int bb = n-aa;
 57             if(aa >= k)
 58             {
 59                 LL xx = N[aa-k]*N[k]%mod;
 60                 ni = quick(xx,mod-2);
 61                 ni = N[aa]*ni%mod;
 62                 sum = sum - ni;
 63                 sum = (sum%mod)+mod;
 64                 sum%=mod;
 65             }
 66             if(bb >= k)
 67             {
 68                 LL xx = N[bb-k]*N[k]%mod;
 69                 ni = quick(xx,mod-2);
 70                 ni = N[bb]*ni%mod; //printf("%lld\n",ni);
 71                 sum = sum - ni;
 72                 sum = (sum%mod)+mod;
 73                 sum%=mod;
 74             }
 75         }
 76         printf("%lld\n",sum);
 77     }
 78 }
 79 int dfs(int n)
 80 {
 81     flag[n] = true;
 82     int i;
 83     for(i = 0; i < vec[n].size(); i++)
 84     {
 85         int x = vec[n][i];
 86         if(!flag[x])
 87         {
 88             cnt[n]+=dfs(x);
 89         }
 90     }
 91     cnt[n]++;
 92     return cnt[n];
 93 }
 94 LL quick(LL n,LL m)
 95 {
 96     LL ask = 1;
 97     n%=mod;
 98     while(m)
 99     {
100         if(m&1)
101             ask = ask*n%mod;
102         n = n*n%mod;
103         m>>=1;
104     }
105     return ask;
106 }
时间: 2024-07-31 15:26:48

treecnt 算法马拉松20(告别美国大选及卡斯特罗)的相关文章

51Nod 算法马拉松21(迎新年)

这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过读后面的题. B完全二叉树的方差,大概看了一遍,好神的样子,跳过. C多项式?好吧没学过FFT和NTT的我肯定不会,跳跳跳. D最大值,哎呦这函数什么破玩意儿,看不懂,跳跳跳. E B君的射击,卧槽毕克大人您出题就算了出这么一道码农题是要闹那样,跳跳跳. F那些年,我们一起讲的故事,卧槽这特么简直就

python数据分析美国大选项目实战(三)

项目介绍 项目地址:https://www.kaggle.com/fivethirtyeight/2016-election-polls 包含了2015年11月至2016年11月期间对于2016美国大选的选票数据,共27列. 项目目的:分析每个月的民意调查统计趋势. 涉及知识点: 高阶函数filter numpy读取文本文件 处理日期格式数据 numpy的切片和索引 numpy的统计方法 列表推导式 数据结构zip Matplotlib进行简单的数据可视化 项目代码 # -*- coding:

随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率,想象为一个n维长方体,有两个平面与这个几何图形相割,于是就变成了求面(体)积问题,一般要去重,n维区域系数:s^n/n!,至于区间问题,直接前缀之差搞定 然后就是悲催的算法马拉松17F题了...其实是道好题来的,只是出题人不知世界上还有这题,然后某大牛把思路理清后把答案直接搬了过来 经典的1*2骨牌覆

从美国大选到双十一盛会,看屌丝如何主宰世界命脉

互联网的可贵之处,不仅在于彻底改变社会架构和历史进程,还让原本处于社会.舆论.消费等底层的人群有了充分表达自己意见.展现自己力量的渠道.从这个角度看,占据人口绝大多数的"屌丝"群体,绝对有能力对站在金字塔顶尖的群体产生巨大影响,甚至能够主宰世界命脉. 而近段时间中美的两件大事:美国大选和双十一盛会,都将屌丝主宰世界命脉的能力发挥地淋漓尽致.虽然美国大选没咱的啥事儿,但双十一你肯定贡献了不少money! 美国大选.双十一盛会:屌丝展现巨大能量 此次美国大选之前,原本希拉里当上总统的呼声最

51nod算法马拉松13

A 取余最长路 不难发现路径可以拆成三条线段,只要知道两个转折点的位置就能计算出答案. 设sum(i,l,r)表示第i行从l到r元素的和,则答案可以表示为sum(1,1,x)+sum(2,x,y)+sum(3,y,n)%p. 前缀和一下转化成(S3[n]-S3[y-1])+S2[y]+(S1[x]-S2[x-1])%p,从小到大枚举y,将所有(S1[x]-S2[x-1])扔到一个集合里,用个set就能轻松实现了. 时间复杂度为O(NlogN). #include<cstdio> #includ

51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就可以A.. 然后之后zcg以奇怪的二分方式发现了如何A掉第一题的第十个点(我记得貌似是什么第5000个数等于511? OwO 就这样没有任何思考含量全凭骗分黑科技过掉了第一题 OwO 然后zcg打开了第二题,发现第二题样例有点问题,然后就发了个帖子,直接去看第三题了 我去瞅了一眼,发现这不是gcd

51nod算法马拉松14

这次太丢人了只搞出来了A到D,那就将就写一写A到D... A 棋盘问题 脑筋急转弯题,不难发现每一次两个人只能染白奇数个格子,所以数数有奇数还是偶数个白格子就行了. #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i

51nod算法马拉松 contest7

A题 链接:http://www.51nod.com/contest/problem.html#!problemId=1417 推荐链接:http://blog.csdn.net/a837199685/article/details/45009337 设美女取得正面概率是p,反面就是(1-p),就是美女取一正一反和一反一正的概率相同,然后推出公式y=((a+b)/2+b)/(2*(a+b)); 1 #include<iostream> 2 #include<cstdio> 3 #i

51NOD 1632 B君的连通(推公式)——算法马拉松16

传送门 B国拥有n个城市,其交通系统呈树状结构,即任意两个城市存在且仅存在一条交通线将其连接.A国是B国的敌国企图秘密发射导弹打击B国的交通线,现假设每条交通线都有50%的概率被炸毁,B国希望知道在被炸毁之后,剩下联通块的个数的期望是多少? Input 一个数n(2<=n<=100000) 接下来n-1行,每行两个数x,y表示一条交通线.(1<=x,y<=n) 数据保证其交通系统构成一棵树. Output 一行一个数,表示答案乘2^(n-1)后对1,000,000,007取模后的值