Http://codeforces.com/gym/101147/problem/B
Test instructions: From the bottom to the top, ask the shortest path length of the non-shaded part.
Solution: To save all the shadow pieces of information, and build their own x-axis shadow block, and then sort, from the bottom of the shadow block up and down, each of the two shadow blocks must have a line between the two, a classification of the discussion can be. Build a complete picture after running Dijkstra (I ran Floyd timeout) can get the answer.
The code is as follows:
#include <bits/stdc++.h> using namespace std;
typedef long Long LL;
typedef pair<double, int> PII;
const int MAXN = 105;
Const double INF = 1e18;
Const double EPS = 1e-10;
int n, L, U;
Double G[MAXN][MAXN];
struct Node {int h, W, D, K;
BOOL operator < (const node& T) const {if (d = = T.D) return k < T.K;
return d < T.D;
}}RECT[MAXN];
void Add_edge (int u, int v, double c) {G[u][v] = g[v][u] = c;}
Double Count (double x, double y) {//cannot be used with int, otherwise multiplying will explode int return sqrt (1.0 * x * x + y * y);} void Build_graph () {for (int i = 0; I <= N, i++) {for (int j = i + 1; j <= N; j + +) {if (i = = 0)
{Add_edge (I, J, RECT[J].D);
Continue
} int up = RECT[I].D + rect[i].h;
int down = RECT[J].D;
if (rect[i].k = = rect[j].k) {Add_edge (I, J, down-up); } else {if (up >=) Add_edge (I, J, U-RECT[I].W-RECT[J].W);
else if (RECT[I].W + rect[j].w >= U) Add_edge (i, J, down-up);
else Add_edge (i, J, Count (U-RECT[I].W-RECT[J].W, down-up));
}}}} double DIS[MAXN];
void Dijkstra () {priority_queue <pii, vector <pii>, greater<pii> > Q;
for (int i = 0; I <= N; i++) dis[i] = INF;
Dis[0] = 0;
Q.push (PII (Dis[0], 0));
while (!q.empty ()) {PII tmp = Q.top ();
Q.pop ();
int u = tmp.second;
if (Dis[u] < Tmp.first) continue;
for (int i = 1; I <= n; i++) {if (U = = i) continue;
Double d = dis[u] + g[u][i];
if (Dis[i] > D) {dis[i] = D;
Q.push (PII (dis[i], i)); }}}} int main () {#ifndef Online_judge freopen ("D:\\in.txt", "R", stdin), #else freopen ("street.in", "R",
STDIN);
#endif int T;
scanf ("%d", &t);
while (t--) {scanf ("%d%d%d", &n, &l, &u); for (int i = 1, h, W, D, K; I<= N;
i++) {scanf ("%d%d%d%d", &h, &w, &d, &k);
Rect[i].h = h;
RECT[I].W = W;
RECT[I].D = D;
RECT[I].K = k;
} rect[0].h = 0;
RECT[0].W = U;
RECT[0].D = 0;
RECT[0].K = 0;
Sort (rect, rect + n + 1);
Build_graph ();
Dijkstra ();
Double ans = L;
for (int i = 1; I <= n; i++) {double tmp = Dis[i] + (l-rect[i].d-rect[i].h);
if (tmp < ans) ans = tmp;
} printf ("%.6f\n", ans);
} return 0; }