标签:
题目大意:
强盗从迷宫的0号点开始走,要求任一时刻走过的路径都是到达当前位置的最短路径,且有多条最短路径时选择字典序小的。如果有多种选择,则等概率选择任一种。现在一共有若干个警卫可以安放在这些节点上,并知道每个节点安放若干个警卫可以打败强盗的概率,求出如何安放可使打败强盗的概率最高。
分析:
要求任一时刻走过的路径都是到达当前位置的最短路径,实际上就是建立一棵字典序最小的最小路径树,强盗从根节点走到叶子节点。然后在树上做树形概率DP就好了。
代码:
1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 5000; 5 const int maxm = 50000; 6 const int maxq = 100000; 7 8 int eto[maxm], enext[maxm], eweight[maxm]; 9 int efirst[maxn], en, sta; 10 int tto[maxm], tnext[maxm], tfirst[maxn], tn; 11 int que[maxq], h, r, dis[maxn]; 12 int n, m, u, v, w, p; 13 bool in[maxn], vis[maxn]; 14 double win[2000][100], f[2000][100]; 15 16 inline void ins (int fr, int to, int wi) 17 { 18 en++; 19 enext[en] = efirst[fr]; 20 efirst[fr] = en; 21 eweight[en] = wi; 22 eto[en] = to; 23 } 24 25 inline void ins2 (int fr, int to) 26 { 27 tn++; 28 tnext[tn] = tfirst[fr]; 29 tfirst[fr] = tn; 30 tto[tn] = to; 31 } 32 33 void Bfs () 34 { 35 memset (dis, 63, sizeof (dis)); 36 memset (que, 0, sizeof (que)); 37 memset (vis, 0, sizeof (vis)); 38 int node, edge, nto; 39 que[h = r = 0] = sta; 40 dis[sta] = 0; 41 while (h <= r) 42 { 43 node = que[h]; 44 vis[node] = 0; 45 for (edge = efirst[node]; edge; edge = enext[edge]) 46 { 47 nto = eto[edge]; 48 if (dis[nto] > dis[node] + eweight[edge]) 49 { 50 dis[nto] = dis[node] + eweight[edge]; 51 if (!vis[nto]) 52 vis[que[++r] = nto] = 1; 53 } 54 } 55 h++; 56 } 57 } 58 59 double max (double a, double b) 60 { 61 return a > b ? a : b; 62 } 63 64 void Dfs (int node) 65 { 66 int size = 0; 67 for (int i = tfirst[node]; i; i = tnext[i]) 68 size++; 69 if (size == 0) 70 { 71 for (int j = 0; j <= p; j++) 72 f[node][j] = win[node][j]; 73 }else 74 { 75 for (int i = tfirst[node]; i; i = tnext[i]) 76 Dfs (tto[i]); 77 double temp[100]; 78 memset (temp, 0, sizeof (temp)); 79 for (int i = tfirst[node]; i; i = tnext[i]) 80 { 81 for (int j = p; j >= 0; j--) 82 { 83 for (int k = 0; k <= j; k++) 84 { 85 temp[j] = max (temp[j], f[tto[i]][k] / size + temp[j - k]); 86 } 87 } 88 } 89 for (int j = p; j >= 0; j--) 90 { 91 for (int k = 0; k <= j; k++) 92 { 93 f[node][j] = max (f[node][j], win[node][j - k] + (1 - win[node][j - k]) * temp[k]); 94 } 95 } 96 } 97 } 98 99 int main () 100 { 101 while (1) 102 { 103 memset (eto, 0, sizeof (eto)); 104 memset (eweight, 0, sizeof (eweight)); 105 memset (enext, 0, sizeof (eweight)); 106 memset (efirst, 0, sizeof (efirst)); 107 memset (tto, 0, sizeof (tto)); 108 memset (tnext, 0, sizeof (tnext)); 109 memset (tfirst, 0, sizeof (tfirst)); 110 memset (in, 0, sizeof (in)); 111 memset (win, 0, sizeof (win)); 112 memset (f, 0, sizeof (f)); 113 scanf ("%d %d", &n, &m); 114 if (n == 0 && m == 0) return 0; 115 sta = en = tn = 0; 116 for (int i = 0; i < m; i++) 117 { 118 scanf ("%d %d %d", &u, &v, &w); 119 ins (u, v, w); 120 ins (v, u, w); 121 } 122 Bfs (); 123 for (int i = 0; i < n; i++) 124 { 125 for (int e = efirst[i]; e; e = enext[e]) 126 { 127 if (dis[eto[e]] == dis[i] + eweight[e]) 128 { 129 if (in[eto[e]] == 0) 130 { 131 ins2 (i, eto[e]); 132 in[eto[e]] = 1; 133 } 134 } 135 } 136 } 137 scanf ("%d", &p); 138 for (int i = 0; i < n; i++) 139 for (int j = 1; j <= p; j++) 140 scanf ("%lf", &win[i][j]); 141 Dfs (0); 142 printf ("%.2lf\n", f[0][p] * 100); 143 } 144 }
标签:
原文地址:http://www.cnblogs.com/lightning34/p/4355437.html