《洛谷P1027 Car的旅行路线》
这题的话不是很难,个人感觉难的地方就是求出矩形第四个点的坐标。
对于第四个点的坐标,先用向量垂直来找出直角顶点,然后就可以用矩形中点的坐标来求出第四个点的坐标。
然后就是连边跑个最短路就行。
中间建图连i -> j,然后就忘了j -> i。(亿点点问题
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<double,int> pii; const int N = 505; const int M = 1e6+5; const LL Mod = 1e9+7; #define rg register #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; int s,t,A,B,tot; struct Node{double x,y;int id;}a[N]; double dis[N],way[N][N],T[N]; bool check(int x,int y,int x1,int y1,int x2,int y2)//判断(x,y)是不是矩形三点里的直角顶点 { if((x1-x)*(y1-y)+(x2-x)*(y2-y) == 0) return true; else return false; } void cal(double x1,double y1,double x2,double y2,double x3,double y3,double &x4,double &y4) { if(check(x1,y1,x2,y2,x3,y3)) { double midx = (x2+x3)/2,midy = (y2+y3)/2; x4 = midx - x1 + midx; y4 = midy - y1 + midy; } else if(check(x2,y2,x1,y1,x3,y3)) { double midx = (x1+x3)/2,midy = (y1+y3)/2; x4 = midx - x2 + midx; y4 = midy - y2 + midy; } else { double midx = (x1+x2)/2,midy = (y1+y2)/2; x4 = midx - x3 + midx; y4 = midy - y3 + midy; } } 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)); } double solve(int pos) { for(rg int i = 1;i <= tot;++i) dis[i] = INF; dis[pos] = 0; priority_queue<pii,vector<pii>,greater<pii> > Q; Q.push(pii{dis[pos],pos}); while(!Q.empty()) { int u = Q.top().second; double d = Q.top().first; Q.pop(); if(d > dis[u]) continue; for(rg int i = 1;i <= tot;++i) { if(i == u) continue; if(dis[i] > dis[u] + way[u][i]) { dis[i] = dis[u] + way[u][i]; Q.push(pii{dis[i],i}); } } } double ans = INF; for(rg int i = 1;i <= tot;++i) if(a[i].id == B) ans = min(ans,dis[i]); return ans; } int main() { int ca;ca = read(); while(ca--) { s = read(),t = read(),A = read(),B = read(); tot = 0; for(rg int i = 1;i <= s;++i) { double x1,y1,x2,y2,x3,y3,x4,y4; cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> T[i]; cal(x1,y1,x2,y2,x3,y3,x4,y4); a[++tot] = {x1,y1,i};a[++tot] = {x2,y2,i}; a[++tot] = {x3,y3,i};a[++tot] = {x4,y4,i}; } for(rg int i = 1;i <= tot;++i){ for(rg int j = 1;j <= tot;++j) { if(a[i].id == a[j].id) way[i][j] = Dis(i,j)*T[a[i].id]; else way[i][j] = Dis(i,j)*t; } } double ans = INF; for(rg int i = 1;i <= tot;++i) if(a[i].id == A) ans = min(ans,solve(i)); printf("%.1f\n",ans); } system("pause"); return 0; }