题面:

传送门

题目描述:

给出有n个节点的树,整数k。题目要求找长度为k,符合规则(good序列)的“点序列”(由节点构成的序列)个数有多少?规则如下:
  • 1.走一条出发点为a1,终点为ak的一条路(允许重复边,重复点)
  • 2.从a1开始,通过最短路径走到a2,然后从a2通过最短路径走到a3,以此类推,直到走到终点
  • 3.如果在上述过程中,至少经过一条“黑边”,则这个序列是good的
 

题目分析:

这道题直接分析确实挺难,难在哪里呢?我们看看这个good序列要满足什么条件:
1.走一条路:这里要注意的就是可以重复点,其他没什么可以引起注意的地方
2.从a1走到a2,a2走到a3......如果这个过程经过了黑边,这个序列就是good序列:
所以刚开始我们的想法是:
找一条黑边两端的端点,然后看看包含这两个端点的序列有多少个,再减去重复的。
 
但是,想法很美好,情况很复杂,我刚开始就是这么想的。后面发现越来越不对劲,就重新看了一下题目,发现了一些重要的突破口:
1.题目的good序列是“至少”经过一条黑边,注意,这里的用词是用“至少”。
2.原题目的最后还提醒了:总共有n^k个序列,算其中good序列有多少个。
然后我就想到了:既然good序列这么难算,不如算算bad序列?
bad序列规则:第一点和第二点不变,第三点:如果在上述过程中,没有经过一条“黑边”,则这个序列是bad的。也就是说:
如果在上述过程中,经过所有的边都是“红边”(包括没经过边),则这个序列是bad的。
 
这时问题就变得好解决一些了:
只要找出所有的bad序列,通过n^k-bad,就可以间接求出good序列。而bad序列有什么特点?上面文字已经介绍完毕,下面我们观察一下图:
这个图中,由上面的bad文字定义可知:bad序列肯定是在三个分开的集合取:{1,2,4,6},{5},{3,7}。进一步发现:在一个集合的内部是连通的,而且互相到达绝不经过黑边。对于三个集合来说,它们直接被“黑边”分隔开了。也就是说:可以通过去掉“黑边”得到上面的集合:
其实也就是有多少个连通分支,这个用dfs很好解决。
 
得到了这个集合后,就是怎么算的问题了。举个例子:对于这个集合:{1,2,4,6},我们只需要选k次就得到了bad序列的总数,也就是4^k。(不明白的同学可以这样想:要得到长度为k的bad序列,也就是要确定k个位置的值。每个位置都可以选4个元素而保证一定是bad序列,根据组合数学的分步原理,就是4^k个bad序列)。每一个集合我们都算出它们的bad序列的个数,加起来就是总的bad序列个数。
 
 
 
AC代码:
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 1e5+5;
const int mod = 1e9+7;
int k;
long long n;
vector<int> G[maxn]; //存图
long long cnt[maxn]; //统计每个集合元素个数
int vis[maxn]; //标记/判断i属于哪个集合 void dfs(int u, int num){
if(vis[u]) return;
vis[u] = num; //标记
for(int i = 0; i < G[u].size(); i++){
dfs(G[u][i], num);
}
} int main(){
scanf("%lld %d", &n, &k);
int u, v;
int is_b;
for(int i = 0; i < n-1; i++){
scanf("%d%d%d", &u, &v, &is_b);
if(!is_b){ //如果不是黑边就加入到图中
G[u].push_back(v);
G[v].push_back(u);
}
} for(int i = 1; i <= n; i++){
if(!vis[i]) dfs(i, i);
} for(int i = 1; i <= n; i++){
cnt[vis[i]]++; //统计每个集合的元素个数
} long long bad = 0;
for(int i = 1; i <= n; i++){
long long ans = 1;
if(cnt[i]){ //如果集合存在
for(int j = 1; j <= k; j++){ //算cnt[i]的k次方
ans = ans*cnt[i]%mod;
}
bad = (bad+ans)%mod;
}
} long long all = 1; //算n的k次方
for(int i = 1; i <= k; i++){
all = all*n%mod;
} printf("%lld\n", (all-bad+mod)%mod); //因为all-bad可能为负数(计算时边取模边算), 所以, 要先加个mod再取模
return 0;
}
 
 
 
 

Codeforces Round #548 C. Edgy Trees的更多相关文章

  1. Codeforces Round 548 (Div. 2)

    layout: post title: Codeforces Round 548 (Div. 2) author: "luowentaoaa" catalog: true tags ...

  2. C. Edgy Trees Codeforces Round #548 (Div. 2) 并查集求连通块

    C. Edgy Trees time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  3. CodeForces Round #548 Div2

    http://codeforces.com/contest/1139 A. Even Substrings You are given a string s=s1s2…sns=s1s2…sn of l ...

  4. Codeforces Round #548

    没打,简单补档 C.Edgy Trees 容斥,把黑边断掉数联通块,每个联通块贡献$siz^k$ #include<cstdio> #include<cstring> #inc ...

  5. C. Edgy Trees Codeforces Round #548 (Div. 2) 【连通块】

    一.题面 here 二.分析 这题刚开始没读懂题意,后来明白了,原来就是一个数连通块里点数的问题.首先在建图的时候,只考虑红色路径上的点.为什么呢,因为为了不走红色的快,那么我们可以反着想只走红色的路 ...

  6. Codeforces Round #548 (Div. 2) C. Edgy Trees

    You are given a tree (a connected undirected graph without cycles) of 

  7. Codeforces Round #548 (Div. 2) F splay(新坑) + 思维

    https://codeforces.com/contest/1139/problem/F 题意 有m个人,n道菜,每道菜有\(p_i\),\(s_i\),\(b_i\),每个人有\(inc_j\), ...

  8. Codeforces Round #548 (Div. 2) E 二分图匹配(新坑) or 网络流 + 反向处理

    https://codeforces.com/contest/1139/problem/E 题意 有n个学生,m个社团,每个学生有一个\(p_i\)值,然后每个学生属于\(c_i\)社团, 有d天,每 ...

  9. Codeforces Round #548 (Div. 2) C dp or 排列组合

    https://codeforces.com/contest/1139/problem/C 题意 一颗有n个点的树,需要挑选出k个点组成序列(可重复),按照序列的顺序遍历树,假如经过黑色的边,那么这个 ...

随机推荐

  1. SQL优化这么做就对了

    目录 前言 SQL优化一般步骤 1.通过慢查日志等定位那些执行效率较低的SQL语句 2.explain 分析SQL的执行计划 3.show profile 分析 4.trace 5.确定问题并采用相应 ...

  2. iPad Pro 涂鸦绘画实用技巧

    iPad Pro 涂鸦绘画实用技巧 绘画,涂鸦,简笔画 pre-requirement iPad Pro Apple Pencil 实用技巧 zoom in, zoom out 应用矢量的特性,灵活缩 ...

  3. CSS border gradient color All In One

    CSS border gradient color All In One CSS Gradient Borders border-image-source & border-image-sli ...

  4. HTML marquee

    HTML marquee 跑马灯 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/marquee https://developer ...

  5. window.locationbar

    window.locationbar demo https://cdn.xgqfrms.xyz/#/operate-tool/select-seat-system/select-detail?temp ...

  6. Typescript & React & optional parameters & default parameters

    Typescript & React & optional parameters & default parameters Typescript & optional ...

  7. Flutter 使用Tabbar不要Title

    原文 Demo 1 import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp ext ...

  8. (转)linux下的系统调用函数到内核函数的追踪

    转载网址:http://blog.csdn.net/maochengtao/article/details/23598433 使用的 glibc : glibc-2.17使用的 linux kerne ...

  9. Flex实现复杂布局

    巧妙利用边框(或者背景颜色)来进行布局. 填上内容和图片(由设计提供切图). 去掉边框. css .business-content-1 { display: flex; /* 弹性布局 */ mar ...

  10. ATP - UI 自动化测试用例管理平台搭建

    用到的工具:python3 + django2 + mysql + RabbitMQ + celery + selenium python3和selenium这个网上很多教程,我不在这一一说明:   ...