点此看题面

大致题意: 给你一棵树,每条边为黑色或红色, 求有多少个三元组\((x,y,z)\),使得路径\((x,y),(x,z),(y,z)\)上都存在至少一条红色边。

容斥

我们可以借助容斥思想,用总方案数减去不合法方案数,就可以得到合法方案数。

一个不合法方案,就要使得路径\((x,y),(x,z),(y,z)\)中,至少存在一条路径是全黑的。

如果我们删去树上的红色边,只留下黑色的边。则可以发现,一个不合法方案,满足至少存在两个点在同一个连通块内。

计算答案

考虑用并查集,统计每一个连通块的点数\(s_i\)。

然后,我们枚举连通块\(i\)使有至少两个点存在于这个连通块中,则可以分两类讨论:

  • 第三个点在这个连通块中,方案数为\(C_{s_i}^2\cdot(n-s_i)\)。
  • 第三个点不在这个连通块中,方案数为\(C_{s_i}^3\)。

这样就能计算出不合法方案数了。

最后用\(C_n^3\)减去不合法方案数即为答案。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 50000
#define X 1000000007
using namespace std;
int n,s[N+5],fa[N+5];
I int getfa(CI x) {return fa[x]^x?fa[x]=getfa(fa[x]):x;}
int main()
{
RI i,x,y,t=0;char op;for(scanf("%d",&n),i=1;i<=n;++i) fa[i]=i;//初始化并查集
for(i=1;i^n;++i) scanf("%d%d",&x,&y),cin>>op,op=='b'&&(x=getfa(x))^(y=getfa(y))&&(fa[x]=y);//只留黑色边
for(i=1;i<=n;++i) ++s[getfa(i)];for(i=1;i<=n;++i) i==getfa(i)&&//统计连通块点数,枚举连通块算答案
(t=((1LL*s[i]*(s[i]-1)>>1)%X*(n-s[i])+1LL*s[i]*(s[i]-1)%X*(s[i]-2)%X*(X+1)/6+t)%X);//分两类情况统计不合法方案数
return printf("%d",(1LL*n*(n-1)%X*(n-2)%X*(X+1)/6-t+X)%X),0;//容斥求出合法方案数
}

【51nod1253】Kundu and Tree(容斥+并查集)的更多相关文章

  1. 51nod-1253: Kundu and Tree

    [传送门:51nod-1253] 简要题意: 给出一棵n个点的树,树上的边要么为黑,要么为红 求出所有的三元组(a,b,c)的数量,满足a到b,b到c,c到a三条路径上分别有至少一条红边 题解: 显然 ...

  2. ARC 101E.Ribbons on Tree(容斥 DP 树形背包)

    题目链接 \(Description\) 给定一棵\(n\)个点的树.将这\(n\)个点两两配对,并对每一对点的最短路径染色.求有多少种配对方案使得所有边都至少被染色一次. \(n\leq5000\) ...

  3. [ARC101E]Ribbons on Tree(容斥,dp)

    Description 给定一棵有 \(n\) 个节点的树,满足 \(n\) 为偶数.初始时,每条边都为白色. 现在请你将这些点两两配对成 \(\frac{n}{2}\) 个无序点对.每个点对之间的的 ...

  4. 2017 ACM/ICPC 新疆赛区 I 题 A Possible Tree 带权并查集

    传送门 题意:给定一棵带权树的形态, 但是并不知道每天条边的具体权重. 然后给m个信息, 信息格式为u v val, 表示在树上u 到 v 的路径上经过的边的权重的异或和为val, 问前面最多有多少个 ...

  5. CodeForces 593D Happy Tree Party [LCA+并查集]

    题意:给一棵树,每条边有一个权值,给两种操作,第一种是询问y向下整除从a到b的最短路径中每条边的权值后y的值,第二种是改变某条边的权值. 思路:y的最大值为1e18,最多除大于等于2的数不超过60次即 ...

  6. Codeforces Round #329 (Div. 2) D. Happy Tree Party(LCA+并查集)

    题目链接 题意:就是给你一颗这样的树,用一个$y$来除以两点之间每条边的权值,比如$3->7$,问最后的y的是多少,修改操作是把权值变成更小的. 这个$(y<=10^{18})$除的权值如 ...

  7. Minimum Spanning Tree.prim/kruskal(并查集)

    开始了最小生成树,以简单应用为例hoj1323,1232(求连通分支数,直接并查集即可) prim(n*n) 一般用于稠密图,而Kruskal(m*log(m))用于系稀疏图 #include< ...

  8. 51Nod1253 Kundu and Tree 容斥原理

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1253.html 题目传送门 - 51Nod1253 题意 树包含 N 个点和 N-1 条边.树的边有 ...

  9. 51nod1253 Kundu and Tree

    树包含N个点和N-1条边.树的边有2中颜色红色('r')和黑色('b').给出这N-1条边的颜色,求有多少节点的三元组(a,b,c)满足:节点a到节点b.节点b到节点c.节点c到节点a的路径上,每条路 ...

随机推荐

  1. LeetCode刷题191126

    博主渣渣一枚,刷刷leetcode给自己瞅瞅,大神们由更好方法还望不吝赐教.题目及解法来自于力扣(LeetCode),传送门. 今天状态不好,划水第二天. 算法: 题号:20 给定一个只包括 '(', ...

  2. crontab -e 报错(E518: Unknown option: foldenable)

    crontab 默认编辑器为vi,不支持foldenable #crontab -e Error detected while processing /root/.vimrc: line : E518 ...

  3. 31.Java基础_日期/日期格式/日历类

    Date类 Date对象构造方法 Date对象常用方法 import java.util.*; public class test { public static void main(String[] ...

  4. ACM课内练习_1

    题意很简单就是一个一个素数因子只有2,3,5,7的整数,让你求它的约束的个数(暴力会超时),一开始的思路是先计算2,3,5,7这四个素数因子的个数,求出来之后想了很久没有想出他们个数和约束个数之间的数 ...

  5. win10 安装cuda和cudnn

    首先通过nvidia-smi 查看自己的显卡驱动对应的cuda版本. 参考:https://blog.csdn.net/qq_40212975/article/details/89963016 再去官 ...

  6. [Vue 牛刀小试]:第十三章 - Vue Router 基础使用再探(命名路由、命名视图、路由传参)

    一.前言 在上一章的学习中,我们简单介绍了前端路由的概念,以及如何在 Vue 中通过使用 Vue Router 来实现我们的前端路由.但是在实际使用中,我们经常会遇到路由传参.或者一个页面是由多个组件 ...

  7. 【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素

    题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 ...

  8. 解决IDEA中的DashBoard 不显示端口号

    第一步:找到.idea目录下的workspace.xml文件 第二步:找到下图位置 并添加红色部分代码 添加代码如下: <option name="configurationTypes ...

  9. python frozenset

    1. 一旦初始化,并不可以改变 2. 可以作为字典的键值

  10. PalletOne调色板跨链的ETH提币实现

    实现区块链的跨链,最主要的诉求就是Token的转移,而Token的跨链转移又分为充币和提币2种操作.以PalletOne调色板来说,如果要把ETH跨链到PalletOne上来流转,就是ETH的充币操作 ...