原题传送门
比较复杂的一道DP。
设两点(i,j)之间最短路为dis[i][j],则
可转化为:
将该式前后分立,可得:
对于每个到达的点k,b(k)可从k相邻的点的b得出。
代码:
1 #include2 #define sir(i, p) for(sides *i = star[p]; i; i = i -> aftr) 3 using namespace std; 4 const int N = 1e3 + 5; 5 int n, m, l, r, a[N], q[N], dis[N], ind[N]; 6 double pout[N]; 7 long double bck[N], rnt[N]; 8 priority_queue , int> > queues; 9 bool vis[N]; 10 struct sides { 11 int vv, sis; 12 sides *aftr; 13 long double ends; 14 }*star[N], lenss[N << 3]; 15 inline void moree (int x, int y, int z, double w) ; 16 void pushups (int x) ; 17 void solve (int x) { 18 dis[x] = 0; 19 queues.push (make_pair (0, x)); 20 while (!queues.empty()) { 21 int u = queues.top().second; 22 queues.pop(); 23 if (vis[u]) 24 continue; 25 vis[u] = 1; 26 sir (i, u) 27 if (dis[i -> vv] > dis[u] + i -> sis) { 28 dis[i -> vv] = dis[u] + i -> sis; 29 queues.push (make_pair (-dis[i -> vv], i -> vv)); 30 } 31 } 32 return ; 33 } 34 void doit (int x) { 35 for (int p = r; p > 1; p --) { 36 int u = q[p]; 37 sir (i, u) 38 if(dis[i->vv] == dis[u]+i->sis) { 39 int v = i->vv; bck[u] += i->ends*bck[v]; 40 } 41 pout[u] += a[x]*rnt[u]*bck[u]; 42 bck[u] += (long double)a[u]/rnt[u]; 43 } 44 return ; 45 } 46 int main() { 47 scanf ("%d%d", &n, &m); 48 for (int i = 1; i <= n; i ++) 49 scanf("%d", &a[i]); 50 for (int i = 1; i <= m; i ++) { 51 int x, y, z; 52 double w; 53 scanf("%d%d%d%lf", &x, &y, &z, &w); 54 moree(x, y, z, w); 55 } 56 for (int i = 1; i <= n; i ++) { 57 memset (rnt, 0, sizeof rnt); 58 memset (bck, 0, sizeof bck); 59 memset (vis, 0, sizeof vis); 60 memset (dis, 0x3f, sizeof dis); 61 solve (i); 62 pushups (i); 63 doit (i); 64 } 65 for (int i = 1; i <= n; i ++) 66 printf ("%.10f\n", pout[i]); 67 return 0; 68 } 69 inline void moree (int x, int y, int z, double w) { 70 static int _; sides* ls; 71 ls = &lenss[++_]; 72 ls -> vv = y; 73 ls -> sis = z; 74 ls -> ends = w; 75 ls -> aftr = star[x]; 76 star[x] = ls; 77 ls = &lenss[++_]; 78 ls -> vv = x; 79 ls -> sis = z; 80 ls -> ends = w; 81 ls -> aftr = star[y]; 82 star[y] = ls; 83 return ; 84 } 85 void pushups (int x) { 86 q[r = 1] = x; 87 l = 0; 88 rnt[x] = 1; 89 for (int i = 1; i <= n; i ++) 90 sir (j, i) { 91 if (dis[i] + j -> sis == dis[j -> vv]) 92 ind[j -> vv] ++; 93 } 94 while (r > l) { 95 int u = q[++ l]; 96 sir(i, u) 97 if (dis[u] + i -> sis == dis[i -> vv]) { 98 if (!-- ind[i -> vv]) 99 q[++r] = i -> vv; 100 rnt[i -> vv] += rnt[u] * i -> ends; 101 } 102 } 103 return ; 104 }int