【NOIP2001】Car的旅行线路

题目描述:点击此处
解题思路:
平行四边形相对顶点的横坐标、纵坐标之和分别相等。
将所有机场的坐标都算出来之后,再根据题目描述连边,从出发地的四个机场或到达地的四个机场分别做单源点最短路。

实现代码:

#include<cstdio> 
#include<cstring>
#include<cmath> 
#include<algorithm> 
#include<queue> 
#include<climits> 
using namespace std; 
#define MAXS 100
int n,s,t,a,b,x[MAXS*4+10],y[MAXS*4+10]; 
double dist[MAXS*4],ans; 
queue<int>q; 
bool vis[MAXS*4+10]; 
struct node{ 
    int v; 
    double wt; 
    node *next; 
}edge[MAXS*MAXS*4*4+10],*adj[MAXS*4+10],*ecnt; 
double straight_dist(int x1,int y1,int x2,int y2){
    int t1=x1-x2,t2=y1-y2;
    return sqrt(t1*t1+t2*t2);
}
void addedge(int u,int v,double wt){ 
    node *p=++ecnt; 
    p->v=v; 
    p->wt=wt; 
    p->next=adj[u]; 
    adj[u]=p; 
}
void find_four(int i){
    double a,b,c;
    int t1,t2,rp;
    a=straight_dist(x[i*4-1],y[i*4-1],x[i*4-2],y[i*4-2]);
    b=straight_dist(x[i*4-1],y[i*4-1],x[i*4-3],y[i*4-3]);
    c=straight_dist(x[i*4-3],y[i*4-3],x[i*4-2],y[i*4-2]);
    if(a>b&&a>c)
        rp=3,t1=1,t2=2;
    else if(b>a&&b>c)
        rp=2,t1=1,t2=3;
    else
        rp=1,t1=2,t2=3;
    x[i*4]=x[i*4-t1]+x[i*4-t2]-x[i*4-rp];
    y[i*4]=y[i*4-t1]+y[i*4-t2]-y[i*4-rp];
}
void read_prepare(){ 
    int i,j,k; 
    double wt; 
    scanf("%d%d%d%d",&s,&t,&a,&b); 
    for(i=1;i<=s;i++){ 
        for(j=3;j;j--) 
            scanf("%d%d",&x[i*4-j],&y[i*4-j]); 
        double ti; 
        find_four(i);
        scanf("%lf",&ti); 
        for(j=0;j<=3;j++) 
            for(k=j+1;k<=3;k++){ 
                wt=straight_dist(x[i*4-j],y[i*4-j],x[i*4-k],y[i*4-k])*ti; 
                addedge(i*4-j,i*4-k,wt); 
                addedge(i*4-k,i*4-j,wt); 
            } 
    } 
    for(i=1;i<=s*4;i++) 
        for(j=1;j<=s*4;j++){ 
            if((i+3)/4==(j+3)/4) 
                continue; 
            wt=straight_dist(x[i],y[i],x[j],y[j])*t; 
            addedge(i,j,wt); 
            addedge(j,i,wt); 
        } 
} 
void spfa(int st){ 
    vis[st]=1; 
    q.push(st); 
    for(int i=1;i<=s*4;i++) 
        dist[i]=INT_MAX/2; 
    dist[st]=0; 
    while(!q.empty()){ 
        int u=q.front(),v; 
        double wt; 
        q.pop(); 
        vis[u]=0; 
        for(node *p=adj[u];p;p=p->next){ 
            v=p->v,wt=p->wt; 
            if(dist[u]+wt<dist[v]){ 
                dist[v]=dist[u]+wt; 
                vis[v]=1; 
                q.push(v); 
            } 
        } 
    } 
} 
int main() 
{ 
    scanf("%d",&n); 
    while(n--){ 
        memset(adj,0,sizeof adj); 
        ecnt=&edge[0]; 
        read_prepare(); 
        int i,j; 
        ans=INT_MAX; 
        for(i=0;i<=3;i++){ 
            spfa(a*4-i); 
            for(j=0;j<=3;j++) 
                if(dist[b*4-j]<ans) 
                    ans=dist[b*4-j]; 
        } 
        printf("%.2lf\n",ans); 
    } 
}

你可能感兴趣的:(C++,图论,noip)