Car的旅行路线

链接

19:34
我觉得最短路可以啃掉这道题。

20:09

这蛇皮建边我可以吐槽一天!!!!!!!!

21:00

我去,代码半小时,查错一小时

21:05
我,终于,A了
瘫软

进入题解

其实思维不难,就是一道最短路,是个人都看出来了

就是这个建图毒瘤啊

首先是个矩形已知三个点求第四个点(xa+xb-xc,ya+yb-yc)这个旁边大佬给我的公式(a,b是对顶点,c是另一个已知点)

然后四个点之间都是可以建边的,确切点说

所有点之间都可以建边,一共4n个点

所以打消了我add前向星的想法,因为到处哪里都是边,还不如邻接矩阵

可是我懒得写了,于是取消了add,在spfa里开始暴力瞎跑

对于同一个城市的点代价乘以ti,否则乘以T

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
struct node{
	double x,y;
	int id;
}e[1000101];
int fir[1000101],cnt=0,vis[1000101];
double w[1000101];
double dist[1000101];
double dis(double x1,double y1,double x2,double y2){
	return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
int n,m,s,ed;
void spfa(int st){
	for(int i=1;i<=4*n;i++)dist[i]=99999999.9,vis[i]=0;
	for(int i=st;i<=st+3;i++)dist[i]=0.0;
	queue<int> q;
	q.push(st);vis[st]=1;
	q.push(st+1); vis[st+1]=1;
	q.push(st+2); vis[st+2]=1;
	q.push(st+3); vis[st+3]=1;
	while(!q.empty()){
		int x=q.front();q.pop();vis[x]=0;
		for(int j=1;j<=4*n;j++){
			if(j==x)continue;
			double lala=dis(e[x].x,e[x].y,e[j].x,e[j].y);
			if(e[x].id==e[j].id)lala*=w[e[x].id];
			else lala*=(double)m;
			//cout<<w[1]<<endl;
			if(dist[x]+lala<dist[j]){
				dist[j]=dist[x]+lala;
				if(vis[j]==0){
				vis[j]=1;
				q.push(j); 
				}
			}
		}
	}
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d%d%d",&n,&m,&s,&ed);
		for(int i=1;i<=n*4;i+=4){
			int x1,x2,x3,y1,y2,y3,x4,y4,tt;
			int xx1,xx2,xx3,yy1,yy2,yy3;
			scanf("%d%d%d%d%d%d%lf",&x1,&y1,&x2,&y2,&x3,&y3,&w[i/4+1]);
			double d12=dis(x1,y1,x2,y2);
			double d22=dis(x2,y2,x3,y3);
			double d32=dis(x1,y1,x3,y3);
			if(d12>=d22&&d12>=d32)xx1=x1,yy1=y1,xx2=x2,yy2=y2,xx3=x3,yy3=y3;
			if(d22>=d12&&d22>=d32)xx1=x2,yy1=y2,xx2=x3,yy2=y3,xx3=x1,yy3=y1;
			if(d32>=d22&&d32>=d12)xx1=x1,yy1=y1,xx2=x3,yy2=y3,xx3=x2,yy3=y2;
			x4=xx1+xx2-xx3;y4=yy1+yy2-yy3;
			e[i].x=x1,e[i].y=y1;e[i+1].x=x2,e[i+1].y=y2;
			e[i+2].x=x3,e[i+2].y=y3;e[i+3].x=x4,e[i+3].y=y4;
			e[i].id=e[i+1].id=e[i+2].id=e[i+3].id=i/4+1;
		}
		spfa(s);
		double ans=99999999.9;
		for(int i=ed*4-3;i<=4*ed;i++)ans=min(ans,dist[i]);
		printf("%.1f",ans);
	}
	return 0;
} 
原文地址:https://www.cnblogs.com/lisuier/p/9637472.html