zoukankan      html  css  js  c++  java
  • C Rencontre CCPC 威海

    C Rencontre CCPC 威海

    给出一棵树,有三个人,每个人都一个集合,表示他们可能会选的点,当三个人确定选的点a,b, c后,d=min(dis(a,v)+dis(b,v)+dis(c,v)),求d的期望值。

    题解:

    这个题目可能会选择的点就是 三个 点的LCA的深度最小的那个点。

    然后推推题目的第二个样例可以发现就是求每一条边的贡献,然后除以最后三个人可以选择的数量的乘积。

    因为选择这个最近的点,所以可以发现三个人走到最短的点经过的边一定只会经过一次,所以其实对于一条边的经过的次数就是三个人可以选择的数量的乘积减去每一个端点的1和2和3的乘积。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 4e5+10;
    typedef long long ll;
    int head[maxn],to[maxn<<1],nxt[maxn<<1],cnt,w[maxn<<1];
    void add(int u,int v,int c){
    	++cnt,to[cnt] = v,nxt[cnt] = head[u],w[cnt] = c,head[u] = cnt;
    	++cnt,to[cnt] = u,nxt[cnt] = head[v],w[cnt] = c,head[v] = cnt;
    }
    ll have[10][maxn],sum;
    double dfsans(int u,int pre){
    	double ans = 0;
    	for(int i=head[u];i;i=nxt[i]){
    		int v = to[i];
    		if(v == pre) continue;
    		ans += dfsans(v,u);
    		ll res1 = 1,res2 = 1;
    		for(int j=1;j<=3;j++) have[j][u]+=have[j][v];
    		for(int j=1;j<=3;j++) res1 = res1 * have[j][v];
    		for(int j=1;j<=3;j++) res2 = res2 * (have[j][0]-have[j][v]);
    		ans += (sum - res2 - res1)*w[i];
    	}
    	return ans;
    }
    
    int main(){
    	int n;
    	scanf("%d",&n);
    	for(int i=1;i<n;i++){
    		int u,v,w;
    		scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w);
    	}
    	sum = 1;
    	for(int i=1;i<=3;i++){
    		int m,x;
    		scanf("%d",&m);
    		sum *= m,have[i][0] = m;
    		while(m--){
    			scanf("%d",&x);
    			have[i][x]++;
    		}
    	}
    	double cur = dfsans(1,0);
    	double ans = cur/(1.0*sum);
    	printf("%.9f
    ", ans);
    	return 0;
    }
    
    
  • 相关阅读:
    里氏替换原则
    开闭原则
    Java Swing 介绍
    redis发布订阅模式
    Spring Cloud Bus消息总线+rabbitmq+Gradle(Greenwich.RELEASE版本)
    文档对象模型(DOM)系列三:处理元素属性
    文档对象模型(DOM)系列二:在DOM元素间移动
    文档对象模型(DOM)系列一:DOM基础
    深入理解javascript中的this 关键字(转载)
    javascript中的函数
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13899198.html
Copyright © 2011-2022 走看看