zoukankan      html  css  js  c++  java
  • P3317 [SDOI2014]重建

    (color{#0066ff}{ 题目描述 })

    T国有N个城市,用若干双向道路连接。一对城市之间至多存在一条道路。

    在一次洪水之后,一些道路受损无法通行。虽然已经有人开始调查道路的损毁情况,但直到现在几乎没有消息传回。

    幸运的是,此前T国政府调查过每条道路的强度,现在他们希望只利用这些信息估计灾情。具体地,给定每条道路在洪水后仍能通行的概率,请计算仍能通行的道路恰有N-1条,且能联通所有城市的概率。

    (color{#0066ff}{输入格式})

    输入的第一行包含整数N。

    接下来N行,每行N个实数,第i+l行,列的数G[i][j]表示城市i与j之间仍有道路联通的概率。

    输入保证G[i][j]=G[j][i],且G[i][i]=0;G[i][j]至多包含两位小数。

    (color{#0066ff}{输出格式})

    输出一个任意位数的实数表示答案。

    你的答案与标准答案相对误差不超过10^(-4)即视为正确。

    (color{#0066ff}{输入样例})

    3
    0 0.5 0.5
    0.5 0 0.5
    0.5 0.5 0
    

    (color{#0066ff}{输出样例})

    0.375
    

    (color{#0066ff}{数据范围与提示})

    1 < N < =50

    数据保证答案非零时,答案不小于10^-4

    (color{#0066ff}{题解})

    根据题目,我们要求的就是

    [ans=sum_{E}prod_{kin E}P_kprod_{k otin E} (1-P_k) ]

    如果没有后面那个东西,显然就是裸的矩阵树定理,但是后面的东西很不好处理,尤其是因为(k otin E)

    那么,考虑容斥一下, 把( otin换成in)

    [ans=sum_{E}prod_{kin E}P_kfrac{prod_{k}(1-P_k)}{prod_{kin E} (1-P_k)} ]

    然后把上面提出来,就成这样了

    [ans=prod_{k}(1-P_k)sum_{E}prod_{kin E}frac{P_k}{(1-P_k)} ]

    这。。。。这是新的边权!!可以矩阵树直接做!

    然后把前面的累乘处理一下即可

    矩阵树第一题

    有两点需要注意

    答案是矩阵的余子式的值,也就是矩阵去掉任一行任一列的行列式的值

    度数矩阵的变化

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const int maxn = 55;
    const double eps = 1e-8;
    double ans = 1, mp[maxn][maxn];
    int n;
    void gauss() {
    	for(int i = 1; i < n; i++) {
    		for(int j = i + 1; j < n; j++) {
    			double now = mp[j][i] / mp[i][i];
    			for(int k = i; k < n; k++) mp[j][k] -= mp[i][k] * now;
    		}
    		ans *= mp[i][i];
    	}
    	ans = fabs(ans);
    }
    int main() {
    	n = in();
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++) 
    			scanf("%lf", &mp[i][j]);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++) {
    			if(fabs(mp[i][j]) <= eps) mp[i][j] = eps;
    			if(fabs(1 - mp[i][j]) <= eps) mp[i][j] = 1 - eps;
    			if(i < j) ans *= (1.0 - mp[i][j]);
    			mp[i][j] = mp[i][j] / (1.0 - mp[i][j]);
    		}
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++)
    			if(i ^ j) mp[i][i] += mp[i][j], mp[i][j] = -mp[i][j];
    	gauss();
    	printf("%.5f", ans);
    	return 0;
    }
    
  • 相关阅读:
    Photoshop CC 与前端那些事
    gulp入門指南
    谈谈css左右等高的几个方法
    angularjs给Model添加拦截过滤器,路由增加限制,实现用户登录状态判断
    前端自动化工具
    React Router
    Sublime Text 3 常用插件安装
    c++ primer学习指导(13)--1.6书店程序
    c++ primer学习指导(12)--1.5.2初识成员函数
    c++ primer学习指导(11)--1.5.1Sales_item类
  • 原文地址:https://www.cnblogs.com/olinr/p/10422879.html
Copyright © 2011-2022 走看看