zoukankan      html  css  js  c++  java
  • [BZOJ2152]聪聪可可

    [BZOJ2152]聪聪可可

    题目大意:

    一棵(n(nle20000))个点的带边权的树,求任选两个点使得路径上边权和是(3)的倍数的概率。

    思路:

    基础树形DP。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=20001;
    struct Edge {
    	int to,w;
    };
    std::vector<Edge> e[N];
    inline void add_edge(const int &u,const int &v,const int &w) {
    	e[u].push_back((Edge){v,w});
    	e[v].push_back((Edge){u,w});
    }
    int f[N][3],cnt;
    void dfs(const int &x,const int &par) {
    	f[x][0]=1;
    	for(unsigned i=0;i<e[x].size();i++) {
    		const int &y=e[x][i].to,&w=e[x][i].w;
    		if(y==par) continue;
    		dfs(y,x);
    		for(register int i=0;i<3;i++) {
    			for(register int j=0;j<3;j++) {
    				if((i+j+w)%3==0) cnt+=f[x][i]*f[y][j];
    			}
    		}
    		for(register int i=0;i<3;i++) {
    			f[x][(i+w)%3]+=f[y][i];
    		}
    	}
    }
    int main() {
    	const int n=getint();
    	for(register int i=1;i<n;i++) {
    		const int u=getint(),v=getint();
    		add_edge(u,v,getint());
    	}
    	dfs(1,0);
    	cnt=cnt*2+n;
    	const int d=std::__gcd(cnt,n*n);
    	printf("%d/%d
    ",cnt/d,n*n/d);
    	return 0;
    }
    
  • 相关阅读:
    ansible
    爬虫框架之scrapy
    Mongodb
    xml 创建 添加节点或属性(自定义,复制)
    web站点崩溃的原因总结
    C# 关闭正在执行的文件
    254. Factor Combinations
    256. Paint House
    156. Binary Tree Upside Down
    170. Two Sum III
  • 原文地址:https://www.cnblogs.com/skylee03/p/9390578.html
Copyright © 2011-2022 走看看