1415: [noi2005] Cong and Coco
Time Limit: 10 sec memory limit: 162 MB
Submit: 475 solved: 279
[Submit] [Status]
Descriptioninput contains two integers, N and E, which are separated by spaces, indicating the number of scenic spots in the forest and the number of routes connecting adjacent scenic spots. The second row contains two integers, C and M, separated by spaces, indicating the numbers of the scenic spots where Cong and Coco were originally located. In Row E, there are two integers in each line. The two integers AI and Bi in line I + represent a path between Scenic Spot AI and scenic spot bi. All the paths are undirected, that is, if we can go from A to B, we can go from B to. Input to ensure that there is no more than one link between any two scenic spots, and there must be a direct or indirect link between Cong and Coco. Output outputs one real number, rounded to three decimal places, indicating the average number of time units after which Cong will eat Coco. Sample input [input Example 1]
4 3
1 4
1 2
2 3
3 4
[Example 2]
9 9
9 3
1 2
2 3
3 4
4 5
3 6
4 6
4 7
7 8
8 9
Sample output [Output Example 1]
1.500
[Output Example 2]
2.167
Hint
[Example 1]
At the beginning, Cong and Coco are at attraction 1 and attraction 4 respectively.
At the first moment, Cong first. She walked around to the Scenic Spot closer to Coco (scenic spot 4), walked to scenic spot 2, and then to scenic spot 3. It is assumed that the walking time is ignored.
After Coco leaves, there are two possibilities:
The first is to go to the Scenic Spot 3, so that Cong and Coco can reach the same scenic spot, where Coco is eaten and the number of steps is 1. The probability is.
The second is to stop at attraction 4 and not be eaten. The probability is.
At the second time, Cong will move closer to Coco (attraction 4) and just take one step to stay at the same attraction as Coco. In this case, Cong will eat Coco in two steps.
Therefore, the average number of steps is 1 * + 2 * = 1.5.
For all data, 1 ≤ n, e ≤ 1000.
For 50% of the data, 1 ≤ n ≤ 50.
Source: The first question of probabilistic DP. It was abused by the water probability DP a few days ago. So we started to brush the probability DP. Idea: The question requires Cong to keep approaching Coco. And keep the label as small as possible. Then we can use spfa to pre-process POS [I] [J]. Pos [I] [J] indicates that the shortest path from vertex I to vertex J is adjacent to vertex I and has the smallest vertex number. That is, when Cong is at the scenic spot I and Coco is at the Scenic Spot J, Cong will go to the scenic spot number in step 1. Thank you for your explanation of spfa! DP [I] [J] indicates that Cong is at vertex I, and coke captures the average number of coke steps at vertex J. W [I, j] indicates the number of J vertex adjacent to vertex I, and t [I] indicates the degree of vertex I.
You can determine the vertex of the next step of cong Cong, that is, POS [POS [I, j], J]. The next step of Coco is W [I, j], the probability is 1/(t [I] + 1). In the next step, the expected DP [POS [I, j], J], W [I, j] After calculation
It is one step more than DP [POS [I, j], J], W [I, j. Cocoa stays in the same place.
So we can get:
DP [I] [J] = (segma (DP [POS [I] [J] [J] [W [J] [k]) + dp [POS [POS [I] [J] [J] [J])/(t [I] + 1 ). I = J hour
Of course DP [I, I] = 0, because Cong and Coco are already at the same point. If POS [POS [I, j], J] = J or POS [I, j] = J, it means that Coke can be eaten at this step, then DP [I, j] = 1.
You can solve this problem by performing a memory search.
For details, see the code:
# Include <stdio. h> # include <string. h >#include <iostream >#include <queue> using namespace STD; const int maxn = 1010; struct node // Edge Structure {int V; int cost; node * Next ;} edge [maxn <1], * head [maxn]; int PTR, POS [maxn] [maxn], vis [maxn], DIST [maxn]; int N, e, SX, ex; double DP [maxn] [maxn]; queue <int> q; void Adde (int u, int v) {edge [PTR]. V = V; edge [PTR]. next = head [u]; edge [PTR]. cost = 1; head [u] = & edge [PTR ++];} void spfa (INT s) // calculate the Shortest Path Obtain the POs [I] [J] {int U, V; node * P; while (! Q. empty () Q. pop (); memset (VIS, 0, sizeof vis); memset (Dist, 0x3f, sizeof Dist); Dist [s] = 0; For (P = head [s]; p! = NULL; P = p-> next) // pre-process the point around the start point {v = p-> V; POS [s] [v] = V; q. push (V); Dist [v] = 1; vis [v] = 1;} while (! Q. Empty () {u = Q. Front (); vis [u] = 0; q. Pop (); For (P = head [u]; P! = NULL; P = p-> next) {v = p-> V; If (Dist [u] + P-> Cost <Dist [v]) {Dist [v] = DIST [u] + P-> cost; POS [s] [v] = POS [s] [u]; // update the optimal decision point if (! Vis [v]) {q. push (V); vis [v] = 1 ;}} else if (Dist [u] + P-> Cost = DIST [v] & Pos [s] [u] <POS [s] [v]) {pos [s] [v] = POS [s] [u]; If (! Vis [v]) {q. push (V); vis [v] = 1 ;}}}} void DFS (int u, int v) // compute Cong at u Coco at v. Cong expected the number of cocoa steps. Memory search {If (DP [u] [v]> = 0) return; int NP, CNT = 0; double sum = 0; node * P; NP = POS [POS [u] [V] [v]; If (Np = V) {DP [u] [v] = 1; return ;} for (P = head [v]; P! = NULL; P = p-> next) {DFS (NP, p-> V); sum + = DP [NP] [p-> V]; CNT ++; // count edge} DFS (NP, V); sum + = DP [NP] [v]; // Add the expected DP [u] [v] = sum/(CNT + 1) + 1; // after taking a step, add 1} int main () {int I, j, a, B; while (~ Scanf ("% d", & N, & E) {scanf ("% d", & Sx, & Ex); PTR = 0; memset (Head, 0, sizeof head); for (I = 1; I <= N; I ++) for (j = 1; j <= N; j ++) DP [I] [J] =-1; for (I = 0; I <E; I ++) {scanf ("% d", &, & B); Adde (a, B); Adde (B, A) ;}for (I = 1; I <= N; I ++) {DP [I] [I] = 0; // The number of directly eaten steps for an encounter is 0 POS [I] [I] = I; spfa (I);} DFS (sx, ex); printf ("%. 3lf \ n ", DP [SX] [Ex]);} return 0 ;}