zoukankan      html  css  js  c++  java
  • Codeforce Round #548(Div2)

      D:(求联通分量个数)

      题意:有两个数n,k,分别代表树的节点个数和一个点集的点的数量

      给你一棵树,树的边有黑色的有红色的,定义满足要求的点集为:这个点集有k个点,并且点集中一个点到达其余点的路径中,必须有一条边是黑色的,求满足要求的点集的数量

      分析:

      emmm其实第一眼看到这个题是没有思路的,但是后来发现,点集总数量为n^k(从n个点中抽取k次),我们可以用 base=n^k减去不满足条件的点集数量就ok

      然后我们来分析一下什么样的点集是不满足条件的:

      已知满足条件的点集是路径上至少有一条黑色边的,所以不满足条件的点集是:点集中任意两点的最短路径的边都是红色的,因此,不满足条件的点集所在的联通分量的边都是红色的,所以不满足的点集的个数就是:

      定义每个联通分量大小为Pi,数量为  sun(Pi^k)

      所以我们只要移除黑色边,求红色边构成图的联通分量的个数以及大小就OK

      代码如下:

      

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=1e5+5;
     5 const int mod=1e9+7;
     6 bool vis[maxn];
     7 vector<int>G[maxn];
     8 int n,k;
     9 int dfs(int v)
    10 {
    11     vis[v]=1;
    12     int t=1;
    13     for(int i=0;i<G[v].size();++i)
    14     {
    15         int to=G[v][i];
    16         if(vis[to]) continue;
    17         t+=dfs(to);
    18     }
    19     return t;
    20 }
    21 ll pow(ll base)
    22 {
    23     int t=base;
    24     for(int i=1;i<k;++i)
    25     {
    26         base*=t;
    27         base%=mod;
    28     }
    29     return base;
    30 }
    31 int main()
    32 {
    33     cin>>n>>k;
    34     for(int i=1;i<n;++i) 
    35     {
    36         int a,b,c;
    37         cin>>a>>b>>c;
    38         if(c==0) G[a].push_back(b),G[b].push_back(a); 
    39     }
    40     int base=pow(n);
    41     int sub=0;
    42     for(int i=1;i<=n;++i)
    43     {
    44         if(vis[i]==0) sub+=pow(dfs(i));
    45         sub%=mod;
    46     }
    47     printf("%d",base-sub>=0?base-sub:base-sub+mod);
    48 }
  • 相关阅读:
    Element Plus表单resetFields重置表单无效
    thinkphp6通过中间件设置跨域
    centos7安装jdk
    面试
    行测-逻辑填空
    行测-语句表达
    行测-片段阅读
    行测-四大文明古国
    基于 OAuth2.0 协议的单点登录系统方案设计
    性能测试知识点+流程
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/10682841.html
Copyright © 2011-2022 走看看