HDU 4035 Maze 期望dp

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4035

Maze

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65768/65768 K (Java/Others)
#### 问题描述 > When wake up, lxhgww find himself in a huge maze. > > The maze consisted by N rooms and tunnels connecting these rooms. Each pair of rooms is connected by one and only one path. Initially, lxhgww is in room 1. Each room has a dangerous trap. When lxhgww step into a room, he has a possibility to be killed and restart from room 1. Every room also has a hidden exit. Each time lxhgww comes to a room, he has chance to find the exit and escape from this maze. > > Unfortunately, lxhgww has no idea about the structure of the whole maze. Therefore, he just chooses a tunnel randomly each time. When he is in a room, he has the same possibility to choose any tunnel connecting that room (including the tunnel he used to come to that room). > What is the expect number of tunnels he go through before he find the exit? #### 输入 > First line is an integer T (T ≤ 30), the number of test cases. > > At the beginning of each case is an integer N (2 ≤ N ≤ 10000), indicates the number of rooms in this case. > > Then N-1 pairs of integers X, Y (1 ≤ X, Y ≤ N, X ≠ Y) are given, indicate there is a tunnel between room X and room Y. > > Finally, N pairs of integers Ki and Ei (0 ≤ Ki, Ei ≤ 100, Ki + Ei ≤ 100, K1 = E1 = 0) are given, indicate the percent of the possibility of been killed and exit in the ith room. #### 输出 > For each test case, output one line “Case k: ”. k is the case id, then the expect number of tunnels lxhgww go through before he exit. The answer with relative error less than 0.0001 will get accepted. If it is not possible to escape from the maze, output “impossible”. ####样例输入 > 3 > 3 > 1 2 > 1 3 > 0 0 > 100 0 > 0 100 > 3 > 1 2 > 2 3 > 0 0 > 100 0 > 0 100 > 6 > 1 2 > 2 3 > 1 4 > 4 5 > 4 6 > 0 0 > 20 30 > 40 30 > 50 50 > 70 10 > 20 60

样例输出

Case 1: 2.000000
Case 2: impossible
Case 3: 2.895522

题意

给你一颗树,你在1号点,每次你会随机选择一个相邻的点走过去(走过的点也可以再走),每个点都有ki的概率被打回1号点,也有ei的可能逃出去。
现在问这个人逃出去要经过的期望次数是多少。

题解

高斯消元要n^3,吃不消,不过可以通过公式转化,解开环。
[port]

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-9;
const double PI = acos(-1.0);

//start----------------------------------------------------------------------

const int maxn=10101;

double dp[maxn],ex[maxn],ki[maxn];
int n;

VI G[maxn];

double A[maxn],B[maxn],C[maxn];
bool dfs(int u,int fa){
    bool child=false;
    int m=G[u].sz();
    double sa=0,sb=0,sc=0;
    rep(i,0,G[u].sz()){
        int v=G[u][i];
        if(v==fa) continue;
        child=true;
        bool su=dfs(v,u);
        if(!su) return su;
        sa+=A[v],sb+=B[v],sc+=C[v];
    }
    if(!child){
        A[u]=ki[u];
        C[u]=B[u]=1-ki[u]-ex[u];
    }else{
        double tmp=(1-ki[u]-ex[u])/m;
        if(fabs(1-tmp*sb)<eps) return false;
        A[u]=(ki[u]+tmp*sa)/(1-tmp*sb);
        B[u]=tmp/(1-tmp*sb);
        C[u]=(1-ki[u]-ex[u]+tmp*sc)/(1-tmp*sb);
    }
    return true;
}

void init(){
    for(int i=1;i<=n;i++) G[i].clear();
}

int main() {
    int tc,kase=0;
    scf("%d",&tc);
    while(tc--){
        scf("%d",&n);
        init();

        rep(i,0,n-1){
            int u,v;
            scf("%d%d",&u,&v);
            G[u].pb(v);
            G[v].pb(u);
        }

        for(int i=1;i<=n;i++){
            scf("%lf%lf",&ki[i],&ex[i]);
            ki[i]/=100;
            ex[i]/=100;
        }

        bool su=dfs(1,-1);

        prf("Case %d: ",++kase);
        if(fabs(1-A[1])<eps||!su) puts("impossible");
        else prf("%.6lf
",C[1]/(1-A[1]));
    }
    return 0;
}

//end-----------------------------------------------------------------------
原文地址:https://www.cnblogs.com/fenice/p/5968242.html