51Nod1253 Kundu and Tree 容斥原理

原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1253.html

题目传送门 - 51Nod1253

题意

  树包含 N 个点和 N-1 条边。树的边有 2 中颜色红色 (‘r‘) 和黑色 (‘b‘) 。给出这 N-1 条边的颜色,求有多少节点的三元组 (a,b,c) 满足:节点 a 到节点 b 、节点 b 到节点 c 、节点 c 到节点 a 的路径上,每条路径都至少有一条边是红色的。注意 (a,b,c) , (b,a,c) 以及所有其他排列被认为是相同的三元组。输出结果对 1000000007 取余的结果。

题解

  把黑色边连接的点搞成一块。

  答案 = 任选 3 个点的方案数 - 在同一个黑色块中选 3 个点的方案数 - 任选三个数,其中两个点在同一个黑色块中的方案数。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=50005;
int read(){
	int x=0;
	char ch=getchar();
	while (!isdigit(ch))
		ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+ch-48,ch=getchar();
	return x;
}
struct Gragh{
	static const int M=N*2;
	int cnt,y[M],z[M],nxt[M],fst[N];
	void clear(){
		cnt=0;
		memset(fst,0,sizeof fst);
	}
	void add(int a,int b,int c){
		y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt;
	}
}g;
int n,dsize[N];
vector <int> sz;
void dfs(int x,int pre){
	dsize[x]=1;
	for (int i=g.fst[x];i;i=g.nxt[i])
		if (g.y[i]!=pre){
			int y=g.y[i];
			dfs(y,x);
			if (g.z[i])
				dsize[x]+=dsize[y];
			else
				sz.push_back(dsize[y]);
		}
}
LL calc(LL x){
	return x*(x-1)*(x-2)/6;
}
int main(){
	n=read();
	for (int i=1;i<n;i++){
		int x=read(),y=read();
		char s[2];
		scanf("%s",s);
		g.add(x,y,s[0]==‘b‘);
		g.add(y,x,s[0]==‘b‘);
	}
	sz.clear();
	dfs(1,0);
	sz.push_back(dsize[1]);
	LL ans=calc(n);
	for (int i=0;i<sz.size();i++)
		ans-=calc(sz[i])+1LL*sz[i]*(sz[i]-1)/2*(n-sz[i]);
	printf("%lld",ans%1000000007);
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/51Nod1253.html

时间: 2024-10-10 11:06:33

51Nod1253 Kundu and Tree 容斥原理的相关文章

51nod1253 Kundu and Tree

树包含N个点和N-1条边.树的边有2中颜色红色('r')和黑色('b').给出这N-1条边的颜色,求有多少节点的三元组(a,b,c)满足:节点a到节点b.节点b到节点c.节点c到节点a的路径上,每条路径都至少有一条边是红色的. 注意(a,b,c), (b,a,c)以及所有其他排列被认为是相同的三元组.输出结果对1000000007取余的结果. Input 第1行:1个数N(1 <= N <= 50000) 第2 - N行:每行2个数加一个颜色,表示边的起始点和结束的以及颜色. Output 输

一些计数题

可能是血(水)考前最后一篇题解了,不过还是写写题解吧. 大部分来源51nod 51nod1253 Kundu and Tree 挺思博的一道题.首先黑色边没用,所以可以把其视为连通块,然后走出该连通块必然要经过至少一条红色边,于是就是总方案数减3个全在一个黑连通块再减去2个在一个黑连通块. #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e4+7,mod=1e9+7; int n,a

[poj1741]Tree(点分治+容斥原理)

题意:求树中点对距离<=k的无序点对个数. 解题关键:树上点分治,这个分治并没有传统分治的合并过程,只是分成各个小问题,并将各个小问题的答案相加即可,也就是每层的复杂度并不在合并的过程,是在每层的处理过程. 此题维护的是树上路径,考虑点分治. 点分治的模板题,首先设点x到当前子树跟root的距离为,则满足${d_x} + {d_y} \le k$可以加进答案,但是注意如果x,y在同一棵子树中,就要删去对答案的贡献,因为x,y会在其所在的子树中在计算一次.同一棵子树中不必考虑是否在其同一棵子树中的

Hackerrank--Kundu and Tree

题目链接 Kundu is true tree lover. Tree is a connected graph having N vertices and N-1 edges. Today when he got a tree, he colored each edge with one of either red(r) or black(b) color. He is interested in knowing how many triplets(a,b,c) of vertices are

HDU5468(dfs序+容斥原理)

Puzzled Elena Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1162    Accepted Submission(s): 339 Problem Description Since both Stefan and Damon fell in love with Elena, and it was really dif

hdu 2841 Visible Trees【容斥原理】

Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1602    Accepted Submission(s): 661 Problem Description There are many trees forming a m * n grid, the grid starts from (1,1). Farm

hdu 4135 Co-prime +hdu 2841 Visible Trees(容斥原理)

Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2263    Accepted Submission(s): 847 Problem Description Given a number N, you are asked to count the number of integers between A and B

【bzoj 4455】小星星(树型DP+容斥原理)

给一个n个点的图和一个n个点的树,求图和树上的点一一对应的方案数.(N<=17)思路:1.在树的结构上进行tree DP,f[i][j]表示树上点 i 对应图上点 j 时,这个点所在子树的方案数.O(n^3).2.我们可以发现如果按这个定义进行DP,“一一对应”的关系挺难保证.若枚举出全排列得到对应关系,这样就C(n,n)=n! 只能拿到暴力分:那么我们就不限制“一一对应”而改为“一对多”的关系进行tree DP,利用容斥原理达到O(2^n)的复杂度.(P.S.至于为什么用容斥原理我也不清楚,待

BZOJ 3589 动态树 树链剖分+容斥原理

题目大意:给定一棵以1为根的有根树,每个节点有点权,提供两种操作: 1.以某个节点为根的子树所有节点权值+x 2.求一些链的并集的点权和,其中这些链都是由某个节点出发指向根 首先子树修改,链上查询,树链剖分的WT~ 然后这些链上的每个点的点权都只能被加一次,肯定不能打标记,由于k<=5,我们考虑容斥原理 总权值=单链-两两之交+三链之交-- 状压枚举即可 两条链的交集求法如下: 1.求两条链底的LCA 2.若LCA的深度小于其中一条链的链顶深度 交集为空 返回0 3.返回一条链 链底为LCA 链