HDU 4035 - Maze

  1 /*
  2 ID:esxgx1
  3 LANG:C++
  4 PROG:hdu4035
  5 */
  6 #include <cstdio>
  7 #include <cstring>
  8 #include <iostream>
  9 #include <algorithm>
 10 using namespace std;
 11
 12 template<int maxn, int maxe>
 13 class graph {
 14     int fw[maxe], t[maxe];
 15     int h[maxn], p;
 16
 17 public:
 18     graph() :p(0) {memset(h, -1, sizeof h);}
 19     void clear() {p = 0, memset(h, -1, sizeof h);}
 20
 21     void addedge(int s, int _t) {
 22         fw[p] = h[s], t[p] = _t;
 23         h[s] = p++;
 24     }
 25
 26     int begin(int s) {return h[s];}
 27     int for_each(int &e, int &_t) {
 28         int ret = e;
 29         if (~e) {
 30             _t = t[e];
 31             e = fw[e];
 32         }
 33         return ret;
 34     }
 35
 36 };
 37
 38 typedef double DB;
 39 const int maxn = 10007;
 40 graph <maxn, maxn*2> g;
 41
 42 int adjn[maxn];
 43 int K[maxn], E[maxn];
 44
 45 DB A[maxn], B[maxn], C[maxn];
 46
 47 #define eps        1e-9
 48
 49 int dfs(int s, int fa)
 50 {
 51     DB bfa = (1.0 - (K[s] + E[s])/100.0) / adjn[s];
 52     C[s] = 1.0 - (E[s]+K[s])/100.0, A[s] = K[s]/100.0, B[s] = bfa;
 53     DB div = 1.0;
 54     for(int e = g.begin(s), t; ~g.for_each(e, t); ) {
 55         if (t != fa) {
 56             dfs(t, s);
 57             A[s] += bfa * A[t], div -= bfa * B[t],
 58             C[s] += bfa * C[t];
 59         }
 60     }
 61     if (div < eps) return 0;
 62     A[s] /= div; B[s] /= div; C[s] /= div;
 63     return 1;
 64 }
 65
 66 int dfs0(int s, DB &ans)
 67 {
 68     DB bfa = (1.0 - (K[s] + E[s])/100.0) / adjn[s];
 69     DB div = 1.0;
 70     C[s] = 1.0 - (E[s]+K[s])/100.0;
 71     for(int e = g.begin(s), t; ~g.for_each(e, t); ) {
 72         if (!dfs(t, s)) return 0;
 73         div -= bfa * (A[t] + B[t]),
 74         C[s] += bfa * C[t];
 75     }
 76     if (div < eps) return 0;
 77     ans = C[s] / div;
 78     return 1;
 79 }
 80
 81 int main(void)
 82 {
 83     #ifndef ONLINE_JUDGE
 84     freopen("in.txt", "r", stdin);
 85     #endif
 86     int T;
 87     scanf("%d", &T);
 88     for(int t = 1; t<=T; ++t, g.clear()) {
 89         memset(adjn, 0, sizeof adjn);
 90         int N;
 91         scanf("%d", &N);
 92         for(int i=1; i<N; ++i) {
 93             int s, t;
 94             scanf("%d%d", &s, &t); --s, --t;
 95             g.addedge(s, t);
 96             g.addedge(t, s);
 97             ++adjn[s], ++adjn[t];
 98         }
 99         for(int i=0; i<N; ++i)
100             scanf("%d%d", &K[i], &E[i]);
101
102         double ans;
103         if (dfs0(0, ans)) printf("Case %d: %.6f\n", t, ans);
104         else printf("Case %d: impossible\n", t);
105     }
106     return 0;
107 }
2014-11-06 22:24:38 Accepted 4035 203MS 1308K 2056 B G++

===========================================

再简短一点:

 1 /*
 2 ID:esxgx1
 3 LANG:C++
 4 PROG:hdu4035
 5 */
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <iostream>
 9 #include <algorithm>
10 using namespace std;
11
12 template<int maxn, int maxe>
13 class graph {
14     int fw[maxe], t[maxe];
15     int h[maxn], p;
16
17 public:
18     graph() :p(0) {memset(h, -1, sizeof h);}
19     void clear() {p = 0, memset(h, -1, sizeof h);}
20
21     void addedge(int s, int _t) {
22         fw[p] = h[s], t[p] = _t;
23         h[s] = p++;
24     }
25
26     int begin(int s) {return h[s];}
27     int for_each(int &e, int &_t) {
28         int ret = e;
29         if (~e) {
30             _t = t[e];
31             e = fw[e];
32         }
33         return ret;
34     }
35
36 };
37
38 typedef double DB;
39 const int maxn = 10007;
40 graph <maxn, maxn*2> g;
41
42 int adjn[maxn];
43 int K[maxn], E[maxn];
44
45 DB A[maxn], B[maxn], C[maxn];
46
47 #define eps        1e-9
48
49 int dfs(int s, int fa)
50 {
51     DB bfa = (1.0 - (K[s] + E[s])/100.0) / adjn[s];
52     C[s] = 1.0 - (E[s]+K[s])/100.0, A[s] = K[s]/100.0, B[s] = bfa;
53     DB div = 1.0;
54     for(int e = g.begin(s), t; ~g.for_each(e, t); ) {
55         if (t != fa) {
56             dfs(t, s);
57             A[s] += bfa * A[t], div -= bfa * B[t],
58             C[s] += bfa * C[t];
59         }
60     }
61     if (div < eps) return 0;
62     A[s] /= div; B[s] /= div; C[s] /= div;
63     return 1;
64 }
65
66 int main(void)
67 {
68     #ifndef ONLINE_JUDGE
69     freopen("in.txt", "r", stdin);
70     #endif
71     int T;
72     scanf("%d", &T);
73     for(int t = 1; t<=T; ++t, g.clear()) {
74         memset(adjn, 0, sizeof adjn);
75         int N;
76         scanf("%d", &N);
77         for(int i=1; i<N; ++i) {
78             int s, t;
79             scanf("%d%d", &s, &t); --s, --t;
80             g.addedge(s, t);
81             g.addedge(t, s);
82             ++adjn[s], ++adjn[t];
83         }
84         for(int i=0; i<N; ++i)
85             scanf("%d%d", &K[i], &E[i]);
86
87         if (dfs(0, -1) && 1-A[0] >= eps)
88             printf("Case %d: %.6f\n", t, C[0] / (1-A[0]));
89         else printf("Case %d: impossible\n", t);
90     }
91     return 0;
92 }
时间: 2024-12-07 12:19:08

HDU 4035 - Maze的相关文章

HDU 4035 Maze(树形概率DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4035 题意:一棵树,从结点1出发,在每个结点 i 都有3种可能:(1)回到结点1 , 概率 Ki:(2)结束,概率 Ei:(3)随机走一条边.(ki+ei+随机走=1) 求到结束需要走的边数的期望. 假设E[i]为点i到结束走边数的期望,则有 (以下m为点的度数) E[i]=ki*E[1]+(1-ei-ki)/m*(E[fa[i]]+1)若i为叶子节点. =ki*E(1)+(1-ki-ei)*E(f

hdu 4035 Maze(期望)

http://acm.hdu.edu.cn/showproblem.php?pid=4035 是一道很好的题目.题意是有一个迷宫,这里有n个房间,每一对房间有且只有一条隧道,一共有n-1条隧道.起初他在1号房间.他若当前在房间i,接下来有三种路径可以走:ki的概率被杀掉直接回到1号房间:ei的概率从该房间逃走,否则它有均等的概率通过隧道走到和i号房间相连的房间.问它从1号房间逃出去要走的隧道数目的期望. 设dp[i]表示在i号房间走出去要通过的隧道的期望,n-1条边将房间连成一颗无根树,对于叶子

HDU 4035 Maze 概率dp 难度:2

http://acm.hdu.edu.cn/showproblem.php?pid=4035 求步数期望,设E[i]为在编号为i的节点时还需要走的步数,father为dfs树中该节点的父节点,son为dfs树种该节点的子节点的集合,kl[i]为被杀掉的概率,ex[i]为逃出的概率 mv[i]=(1-kl[i]-ex[i])/(1+len(son)) 则明显 E[i]=(E[father]+1)*mv[i]+sigma((E[son]+1)*mv[i])+E[1]*K[i] 未知量是E[i],E[

hdu 4035 Maze (概率DP)

Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 1713    Accepted Submission(s): 659 Special Judge Problem Description When wake up, lxhgww find himself in a huge maze. The maze consisted b

hdu 4035 Maze(比较经典的树形期望DP)

Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 1677    Accepted Submission(s): 638 Special Judge Problem Description When wake up, lxhgww find himself in a huge maze. The maze consisted b

HDU 4035 Maze 概率DP 好题

Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 2012    Accepted Submission(s): 802Special Judge Problem Description When wake up, lxhgww find himself in a huge maze. The maze consisted by

HDU 4035 Maze 概率dp+树形dp

题解:点击打开链接 #include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <algorithm> #include <map> #include <cmath> using namespace std; const double eps = 1e-9; const int N = 10010; vector<

【期望DP】 HDU 4035 Maze

通道 题意:一颗树对于在点i有3种情况:1:被杀死回到点1 --- 概率为ki,2:找到出口退出----慨率为ei,3:和该点相连有m条边,随机走一条,求从点1开始到退出的平均需要走的边数 思路: 设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望.E[1]即为所求. 叶子结点: E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1); = ki*E[1] + (1-ki-ei)*E[father[i]] + (1-ki-ei); 非叶子结

HDU 4035:Maze(概率DP)

http://acm.split.hdu.edu.cn/showproblem.php?pid=4035 Maze Special Judge Problem Description 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