[51nod1253]Kundu and Tree
Posted czllgzmzl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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
输出1个数,对应符合条件的3元组的数量。
奇特的思路。。黑边没有什么用...就把黑边相连的合成一个联通块。
只要选择的三个点在不同的联通块内就合法了...
答案就变成 随便选三个点的方案数 - 三个点在同个联通块内的方案数 - 两个点在同个联通块内的方案数
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cmath> 7 #include<cstdlib> 8 #define ll long long 9 #define ull unsigned long long 10 #define ui unsigned int 11 //#define d double 12 #define ld long double 13 const int maxn=50023,modd=1000000007; 14 int c[maxn][4],fa[maxn],sz[maxn]; 15 int i,j,k,n,m; 16 17 int ra,fh;char rx; 18 inline int read(){ 19 rx=getchar(),ra=0,fh=1; 20 while(rx<\'0\'&&rx!=\'-\')rx=getchar(); 21 if(rx==\'-\')fh=-1,rx=getchar(); 22 while(rx>=\'0\')ra=ra*10+rx-48,rx=getchar();return ra*fh; 23 } 24 inline int getfa(int x){return fa[x]!=x?fa[x]=getfa(fa[x]):x;} 25 inline void MOD(int &x){if(x>=modd)x-=modd;} 26 inline void UPD(int &x){if(x<0)x+=modd;} 27 int main(){ 28 n=read(); 29 c[0][0]=1;register int i,j; 30 for(i=1;i<=n;i++){ 31 c[i][0]=sz[i]=1,fa[i]=i; 32 for(j=1;j<=3;j++)MOD(c[i][j]=c[i-1][j-1]+c[i-1][j]);//,printf(" %d %d c:%d\\n",i,j,c[i][j]); 33 } 34 int x,y; 35 for(i=1;i<n;i++){ 36 x=read(),y=read(); 37 if(getchar()==\'b\')x=getfa(x),y=getfa(y),fa[x]=y,sz[y]+=sz[x]; 38 } 39 int ans=c[n][3]; 40 for(i=1;i<=n;i++)if(fa[i]==i) 41 UPD(ans-=(c[sz[i]][3]+1ll*(n-sz[i])*c[sz[i]][2])%modd); 42 printf("%d\\n",ans); 43 }
以上是关于[51nod1253]Kundu and Tree的主要内容,如果未能解决你的问题,请参考以下文章