treecnt 算法马拉松20(告别美国大选及卡斯特罗)
给定一棵n个节点的树,从1到n标号。选择k个点,你需要选择一些边使得这k个点通过选择的边联通,目标是使得选择的边数最少。
现需要计算对于所有选择k个点的情况最小选择边数的总和为多少。
样例解释:
一共有三种可能:(下列配图蓝色点表示选择的点,红色边表示最优方案中的边)
选择点{1,2}:至少要选择第一条边使得1和2联通。

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

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

第一行两个数n,k(1<=k<=n<=100000)
接下来n-1行,每行两个数x,y描述一条边(1<=x,y<=n)
一个数,答案对1,000,000,007取模。
3 2
1 2
1 3
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 }
treecnt 算法马拉松20(告别美国大选及卡斯特罗)的更多相关文章
- 51Nod 算法马拉松21(迎新年)
这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...
- 项目实战利用Python来看美国大选
一.项目介绍 首先分析美国总统竞选这个项目是一个烂大街的项目,但是他的确是一个适合Python新手入门的数据处理项目. 本人在大二刚刚学习了Python数据处理,学习时间不超过5个小时,但是已经可以完 ...
- 数据分析06 /pandas高级操作相关案例:人口案例分析、2012美国大选献金项目数据分析
数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 目录 数据分析06 /pandas高级操作相关案例:人口案例分析.2012美国大选献金项目数据分析 1. ...
- 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3
先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...
- 51NOD 算法马拉松8
题目戳这里:51NOD算法马拉松8 某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod... A.还是01串 水题..怎么乱写应该都可以.记个前缀和然后枚举就行了.时间复杂度 ...
- python数据分析美国大选项目实战(三)
项目介绍 项目地址:https://www.kaggle.com/fivethirtyeight/2016-election-polls 包含了2015年11月至2016年11月期间对于2016美国大 ...
- 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)
题目链接 51nod 算法马拉松 34 Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...
- 51Nod 算法马拉松23 开黑记
惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...
- Python(一)数据结构和算法的20个练习题问答
数据结构和算法 Python 提供了大量的内置数据结构,包括列表,集合以及字典.大多数情况下使用这些数据结构是很简单的. 但是,我们也会经常碰到到诸如查询,排序和过滤等等这些普遍存在的问题. 因此,这 ...
随机推荐
- JForum论坛安装以及部署
转载链接:https://blog.csdn.net/jhyfugug/article/details/79467369 首先安装JForum之前,先准备好安装环境Windows7+JDK+Tomca ...
- C/C++运行时确定字节顺序
字节顺序(英文:Endianness),多字节数据在内存中的存储顺序: 1.对于特定数据,内存空间有起始地址.结束地址: 2.对于数据本身,存在高位字节.地位字节:例如 int data = 0x01 ...
- Mybatis批量添加、更新小结
虽然是很基础的东西,不过难免会忘记,所以写个笔记巩固一下,顺便分享. 实体类: @Data public class EventOrder { private Long id; private ...
- 点击下拉选择触发事件【c#】
<asp:DropDownList ID="ddlRegionList" runat="server" AutoPostBack="true&q ...
- day08 外键字段的增删查改
day08 外键字段的增删查改 今日内容概要 外键字段的增删查改 正反向查询的概念 基于对象的跨表查询(子查询) 基于双下划线的跨表查询(连表操作) 聚合查询与分组查询 F查询和Q查询 前提准备 cl ...
- HTTP 之 options预请求
一.HTTP一共有八种常见请求方法 get:参数在url上,浏览器长度有限制,不安全 post:参数不可见,长度不受限制 put:上传最新内容到指定位置 delete:删除请求的url所表示的资源 h ...
- hashtable深度探索
1.什么是哈希表(hashtable)?为什么要发明哈希表? 首先回答第二个问题,在之前的数据结构中我们学习了数组,链表,二叉树等数据结构,记录在结构中的相对位置是随机的,和记录的关键字之前不存在确定 ...
- Linux系统中安装软件方法总结
Linux系统中安装软件方法总结 [1]Linux系统中安装软件的几种方式 [2] Linux配置yum源(本地源和网络源) [3] SuSE下zypper源配置 [4] SUSE zypper 本地 ...
- vue项目windows环境初始化
下载nodejs zip包并加载到环境变量 nodejs的版本最好使用12版,而不是最新版 npm install webpack -gnpm install -g yarnyarn config s ...
- size_type 和 size_t 的区别
标准库string里面有个函数size,用来返回字符串中的字符个数,具体用法如下:string st("The expense of spirit\n");cout << ...