1. 程式人生 > >GYM - 101147 B.Street

GYM - 101147 B.Street

can ret using gym add 技術分享 color max freopen

題意:

  大矩形代表市場,大矩形當中有很多小矩形樣式的傘。這些小矩形都貼著大矩形的左邊或者右邊且互不相交。小矩形以外的地方都是陽光。求經過大矩形時在陽光下的最短時間。

題解:

  最短路的做法。起點和終點與每個矩形之間連邊,每兩個矩形之間也連邊。

  矩形之間兩邊有三種情況:1.兩個矩形在同一邊(k值相等)或兩個矩形的寬度和大於(不能大於等於)大矩形的寬度

              2.兩個矩形的長度區間不相交(a[i].h+a[i].d<a[j].d||a[j].h+a[j].d<a[i].d)

              3.長度區間相交

技術分享圖片
#include <bits/stdc++.h>
using
namespace std; typedef long long ll; int t, n, vis[105]; double L, U; double diss[105]; struct rec { double h, w, d; int k; }r[105]; struct node { int to; double val; node(int a, double b) { to = a; val = b; } }; vector<node> g[105]; double distance(double x1, double
y1, double x2, double y2) { return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } void add_edge(int u, int v, double val) { g[u].push_back(node(v, val)); g[v].push_back(node(u, val)); } void unite(int u, int v) { double dis; if(r[u].k==r[v].k || r[u].w+r[v].w > U) dis = max(r[u].d-r[v].d-r[v].h, r[v].d-r[u].d-r[u].h);
else { if(r[u].d > r[v].d+r[v].h) dis = distance(r[u].w, r[u].d, U-r[v].w, r[v].d+r[v].h); else if(r[v].d > r[u].d+r[u].h) dis = distance(r[v].w, r[v].d, U-r[u].w, r[u].d+r[u].h); else dis = U-r[u].w-r[v].w; } add_edge(u, v, dis); } void spfa(int s) { queue<int> q; q.push(s); memset(vis, 0, sizeof(vis)); vis[s] = 1; while(!q.empty()) { int v = q.front(); q.pop(); vis[v] = 0; int len = g[v].size(); for(int i = 0; i < len; i++) { if(g[v][i].val+diss[v] < diss[g[v][i].to]) { diss[g[v][i].to] = g[v][i].val+diss[v]; if(!vis[g[v][i].to]) { q.push(g[v][i].to); vis[g[v][i].to] = 1; } } } } } int main() { freopen("street.in","r",stdin); scanf("%d", &t); while(t--) { scanf("%d%lf%lf", &n, &L, &U); for(int i = 0; i <= n+1; i++) { g[i].clear(); if(i) diss[i] = 1e15; } for(int i = 1; i <= n; i++) scanf("%lf%lf%lf%d", &r[i].h, &r[i].w, &r[i].d, &r[i].k); for(int i = 1; i <= n; i++) { add_edge(0, i, r[i].d); add_edge(n+1, i, L-r[i].d-r[i].h); } for(int i = 1; i < n; i++) for(int j = i+1; j <= n; j++) unite(i, j); spfa(0); printf("%.6lf\n", diss[n+1]); } }
View Code

GYM - 101147 B.Street