wikioi 1041 Car的旅行路线

http://wikioi.com/problem/1041/

建图是关键机场通过铁路,城市有4个机场可以到达,可以出发

(告诉3个点有多个情况:1,2为对角,1,3为对角,2,3为对角)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

double map[110][5][110][5];//i的k1到j的k2
int n;
int s,t,a,b;
int x[5],y[5];
struct node
{
    int x[5],y[5];
}zb[110];
int vis[100+10][5];
double d[100+10][5];
const int inf=0x3f3f3f3f;
void tu()//相练习耐心就写吧
{
        for(int i=1;i<=s;i++)
        {
            int st;
            scanf("%d%d%d%d%d%d%d",&x[1],&y[1],&x[2],&y[2],&x[3],&y[3],&st);
            double l1,l2,l3;
            l1=sqrt((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2]));
            map[i][2][i][1]=map[i][1][i][2]=l1*st;
            l2=sqrt((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3]));
            map[i][3][i][1]=map[i][1][i][3]=l2*st;
            l3=sqrt((x[3]-x[2])*(x[3]-x[2])+(y[3]-y[2])*(y[3]-y[2]));
            map[i][3][i][2]=map[i][2][i][3]=l3*st;
            if((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])+(x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])==(x[3]-x[2])*(x[3]-x[2])+(y[3]-y[2])*(y[3]-y[2]))
            {
                x[4]=x[3]+x[2]-x[1];
                y[4]=y[3]+y[2]-y[1];
            }
            else if((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])+(x[3]-x[2])*(x[3]-x[2])+(y[3]-y[2])*(y[3]-y[2])==(x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3]))
            {
                x[4]=x[3]+x[1]-x[2];
                y[4]=y[3]+y[1]-y[2];
            }
            else if((x[3]-x[2])*(x[3]-x[2])+(y[3]-y[2])*(y[3]-y[2])+(x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])==(x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2]))
            {
                x[4]=x[1]+x[2]-x[3];
                y[4]=y[1]+y[2]-y[3];
            }
            for(int j=1;j<=3;j++)
            {
                map[i][4][i][j]=map[i][j][i][4]=sqrt((x[4]-x[j])*(x[4]-x[j])+(y[4]-y[j])*(y[4]-y[j]))*st;
            }
            for(int k=1;k<=4;k++)
            {
                zb[i].x[k]=x[k];
                zb[i].y[k]=y[k];
            }//城市保存个结构
        }
        for(int i=1;i<=s;i++)
        {
            for(int j=i+1;j<=s;j++)
            {
                for(int k1=1;k1<=4;k1++)
                for(int k2=1;k2<=4;k2++)
                {
                    double l5=sqrt((zb[i].x[k1]-zb[j].x[k2])*(zb[i].x[k1]-zb[j].x[k2])+(zb[i].y[k1]-zb[j].y[k2])*(zb[i].y[k1]-zb[j].y[k2]));
                    map[i][k1][j][k2]=map[j][k2][i][k1]=l5*t;
                    //printf("l5==%.3lf map[%d][%d][%d][%d]==%.3lf\n",l5,i,k1,j,k2,map[i][k1][j][k2]);
                }
            }
        }
}
void dij()
{
    double ans=inf;
    for(int l=1;l<=4;l++)//出发位置
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=s;i++)
        for(int j=1;j<=4;j++)d[i][j]=999999.9;
        
        d[a][l]=0;
    for(int i=1;i<=4*s;i++)
    {
        int x,y;
        double m=inf;
        for(int j=1;j<=s;j++)
        {
        for(int k1=1;k1<=4;k1++)if(!vis[j][k1]&&d[j][k1]<=m)
        {
            m=d[j][k1];
            x=j;
            y=k1;
        }
        }
        vis[x][y]=1;
        for(int j=1;j<=s;j++)
        {
        for(int k1=1;k1<=4;k1++)//注意是4个机场
        {
            d[j][k1]=min(d[j][k1],d[x][y]+map[x][y][j][k1]);
        }
        }
        for(int j=1;j<=4;j++)ans=min(ans,d[b][j]);
    }
    }
    printf("%.1lf\n",ans);
}
int main()
{
    scanf("%d",&n);
    for(int ji=1;ji<=n;ji++)
    {
        memset(map,0,sizeof(map));
        scanf("%d%d%d%d",&s,&t,&a,&b);
        tu();
        dij();
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值