zoukankan      html  css  js  c++  java
  • 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
    ",ni);
     71                 sum = sum - ni;
     72                 sum = (sum%mod)+mod;
     73                 sum%=mod;
     74             }
     75         }
     76         printf("%lld
    ",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 }
  • 相关阅读:
    C++ Boost Thread 编程指南
    boost的Any库学习
    人生规划,关注未来,才能持续发展
    察言观色—看穿他人心理的6种方法
    MS SQL Server 2008发布与订阅
    WebService代理类中对枚举类型的序列化
    Winform注册和注销全局快捷键
    sql server中如何为数据表添加表的描述MS_Description
    如何修改SQL Server 2008数据库服务器名称
    IIS 上发布网站后编译器错误信息: CS0016: 解决办法
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/6115763.html
Copyright © 2011-2022 走看看