Saving James Bond 【HDU - 1245】【題意+精度處理過後的Dijkstra】
阿新 • • 發佈:2019-01-06
題目連結(不止是C++、G++也是能過的)
題意:一開始壓根沒讀懂題意,可能就是因為把半徑和直徑看錯了。
在中心島為(0,0)直徑為15的島上,就是主人公的位置了,然後,我們的整個逃生區域是(-50,-50)為左下角,(50,50)為右下角的這麼一個區域,只需要跑出這個區域,就是贏了,所以,我們只需要建兩個虛點:(一)、中心島的點;(二)、區域外的點。以此跑Dijkstra即可。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 //#define INF 0x3f3f3f3f #define efs 1e-7 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 105; const double INF = 1e9 + 7.; int N, head[maxN], cnt, step[maxN]; double D, mp[maxN][maxN], dis[maxN]; struct node { double x, y; node(double a=0, double b=0):x(a), y(b) {} }a[maxN]; double Dis(int i, int j) { return sqrt((a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y)); } struct Eddge { int nex, to; double val; Eddge(int a=0, int b=0, double c=0):nex(a), to(b), val(c) {} }edge[maxN*maxN]; inline void addEddge(int u, int v, double val) { edge[cnt] = Eddge(head[u], v, val); head[u] = cnt++; } inline double Min_4(double e1, double e2, double e3, double e4) { return min(min(e1, e2), min(e3, e4)); } struct point { int id, step; double val; point(int a=0, double b=0, int c=0):id(a), val(b), step(c) {} friend bool operator < (point e1, point e2) { if(e1.val == e2.val) return e1.step > e2.step; return e1.val > e2.val; } }; void Dijkstra(int pos) { priority_queue<point> Q; Q.push(point(pos, 0, 0)); dis[pos] = 0.; step[pos] = 0; while(!Q.empty()) { point tmp = Q.top(); Q.pop(); int u = tmp.id; for(int i=head[u]; i!=-1; i=edge[i].nex) { int v = edge[i].to; double cost = edge[i].val; if(dis[v] > dis[u] + cost) { dis[v] = dis[u] + cost; step[v] = step[u] + 1; Q.push(point(v, dis[v], step[v])); } else if(dis[v] >= dis[u] + cost + efs && step[v] > step[u] + 1) { step[v] = step[u] + 1; Q.push(point(v, dis[v], step[v])); } } } } inline void init() { a[0] = node(); cnt = 0; memset(head, -1, sizeof(head)); for(int i=0; i<=N+1; i++) { dis[i] = INF; step[i] = 0; } } int main() { while(scanf("%d%lf", &N, &D)!=EOF) { init(); for(int i=1; i<=N; i++) { double tmp = 0.; scanf("%lf%lf", &a[i].x, &a[i].y); if(Dis(0, i) < 7.5 + efs || a[i].x > 50. || a[i].x < -50. || a[i].y > 50. || a[i].y < -50.) continue; for(int j=1; j<i; j++) { if((tmp = Dis(i, j)) <= D + efs) { addEddge(i, j, tmp); addEddge(j, i, tmp); } } if((tmp = Dis(0, i) - 7.5) <= D + efs) addEddge(0, i, tmp); if((tmp = Min_4(a[i].x + 50, a[i].y + 50, 50 - a[i].x, 50 - a[i].y)) <= D + efs) addEddge(i, N + 1, tmp); } Dijkstra(0); if(dis[N+1] < INF) printf("%.2lf %d\n", dis[N+1], step[N+1]); else printf("can't be saved\n"); } return 0; }