zoukankan      html  css  js  c++  java
  • 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-----------------------------------------------------------------------
  • 相关阅读:
    对软件工程的理解及问题
    使用Junit等工具进行单元测试
    软件工程
    进销存管理系统——可行性分析
    使用Junit等工具进行单元测试
    两个人的分组
    物联网软件工程 认识与问题
    二人项目
    使用Junit等工具进行单元测试
    软件工程
  • 原文地址:https://www.cnblogs.com/fenice/p/5968242.html
Copyright © 2011-2022 走看看