hdu:4035Maze

題目鏈接

hdu4035

題意

有n個房間,由n-1條通道連通起來,實際上就形成了一棵樹,從結點1出發,開始走,在每個結點i都有3種可能:
1.被殺死,回到結點1處(概率爲ki)
2.找到出口,走出迷宮 (概率爲ei)
3.和該點相連有m條邊,隨機走一條
求:走出迷宮所要走的步數的期望值。

題解

設:i號點走出迷宮步數的期望爲Ei ,父親爲Fi ,兒子爲Chi ,兒子數目爲m 那麼E1 即爲所求。
容易寫出:
對於葉子節點i:
Ei=kiE1+(1kiei)(EFi+1)=kiE1+(1kiei)EFi+(1kiei)
對於非葉子節點i:
Ei=kiE1+(1kiei)/m(EFi+1+(EChi+1))=kiE1+(1kiei)/mEFi+(1kiei)/mEChi+1kiei
我們發現,對於每個點,他的期望都與他父親的期望和1號點的期望有關。我們可以寫出這種形式:
Ei=AiE1+BiEFi+Ci
對於非葉子節點Ci 的值還與它的兒子有關。設它的兒子爲j。
Ej=(AjE1+BjEFj+Cj)=(AjE1+BjEi+Cj)
將它代入上式:
Ei=kiE1+(1kiei)/mEFi+(1kiei)/m(AjE1+BjEi+Cj)+1kiei
化簡後有:
(1(1kiei)/mBj)Ei=(ki+(1kiei)/mAj)E1+(1kiei)/mEFi+(1kiei)+(1kiei)/mCj
即:
Ai=(ki+(1kiei)/mAj)/(1(1kiei)/mBj)Bi=(1kiei)/m/(1(1kiei)/mBj)Ci=((1kiei)+(1kiei)/mCj)/(1(1kiei)/mBj)
現在Ai,Bi,Ci 只與他們的兒子kiei 有關了。於是可以從下往上遞推,推出A1,B1,C1 即可。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;

struct edge{
    int x,next;
}ed[20010];
int first[10010],du[10010],tot,n,m,x,y,T,id;
double a[10010],b[10010],c[10010],e[10010],k[10010];

void add(int x,int y){
    ed[++tot].x=y;
    ed[tot].next=first[x];
    first[x]=tot;
} 
bool dfs(int x,int y){
    int m=du[x]; 
    a[x]=k[x]; 
    b[x]=(1-k[x]-e[x])/m;
    c[x]=1-k[x]-e[x];
    double tmp=0;
    for(int i=first[x];i;i=ed[i].next)
    if(ed[i].x!=y){
        if(!dfs(ed[i].x,x)) return false;
        a[x]+=(1-k[x]-e[x])/m*a[ed[i].x];
        c[x]+=(1-k[x]-e[x])/m*c[ed[i].x];
        tmp+=(1-k[x]-e[x])/m*b[ed[i].x];
    }
    if(fabs(tmp-1)<1e-9) return false;
    a[x]/=1-tmp;
    b[x]/=1-tmp;
    c[x]/=1-tmp;
    return true;
}
int main(){
    for(scanf("%d",&T);T;T--,id++){
        memset(first,0,sizeof(first));
        memset(du,0,sizeof(du));
        scanf("%d",&n); tot=0;
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            add(x,y); add(y,x);
            du[x]++; du[y]++;
        }
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&k[i],&e[i]);
            k[i]/=100.0; e[i]/=100.0;
        }
        printf("Case %d: ",id+1);
        if(dfs(1,0)&&fabs(1-a[1])>1e-9) printf("%.6f\n",c[1]/(1-a[1]));
        else puts("impossible");
    }
    return 0;
}
發佈了60 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章