《洛谷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;
}
View Code

 

posted @ 2020-09-30 15:15  levill  阅读(161)  评论(0编辑  收藏  举报