把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P1027 Car的旅行路线

题面传送门
显然这是一道\(SPFA\)水题,难点在建边。
题目中给三个点求另一个点,那么只要找到对角线,然后把另一个点对称过去就好了。
代码实现:

#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int n,m,k,x[139][5],y[139][4],h[539],head,ans,tot,pus,sx,sy,sz,now,cur,ts,a,b,t[139],s;
double d[539];
struct yyy {
	int to;
	double w;
	int z;
}f[80039],tmp;
inline void add(int x,int y,double z) {
	f[++head]=(yyy) {
		y,z,h[x]
	};
	h[x]=head;
}
queue<int> q;
int main() {
	register int i,j,k,sh;
	scanf("%d",&s);
	while(s--) {
		head=0;
		memset(h,-1,sizeof(h));
		for(i=1; i<=500; i++) d[i]=1e9;
		scanf("%d%d%d%d",&n,&ts,&a,&b);
		for(i=1; i<=n; i++) {
			for(j=1; j<=3; j++)scanf("%d%d",&x[i][j],&y[i][j]);
			ans=0;
			for(j=1; j<=3; j++) {
				for(k=j+1; k<=3; k++) {
					if(sqrt((x[i][j]-x[i][k])*(x[i][j]-x[i][k])+(y[i][j]-y[i][k])*(y[i][j]-y[i][k]))>ans) {
						ans=sqrt((x[i][j]-x[i][k])*(x[i][j]-x[i][k])+(y[i][j]-y[i][k])*(y[i][j]-y[i][k]));
						x[i][4]=x[i][j]+x[i][k]-x[i][6-k-j];
						y[i][4]=y[i][j]+y[i][k]-y[i][6-k-j];
					}
				}
			}
			scanf("%d",&t[i]);
			for(j=1; j<=4; j++) {
				for(k=j+1; k<=4; k++) {
					add(i*4-4+j,i*4-4+k,sqrt((x[i][j]-x[i][k])*(x[i][j]-x[i][k])+(y[i][j]-y[i][k])*(y[i][j]-y[i][k]))*t[i]);
					add(i*4-4+k,i*4-4+j,sqrt((x[i][j]-x[i][k])*(x[i][j]-x[i][k])+(y[i][j]-y[i][k])*(y[i][j]-y[i][k]))*t[i]);
				}
			}
		}
		for(i=1; i<=n; i++) {
			for(j=1; j<=4; j++) {
				for(k=i+1; k<=n; k++) {
					for(sh=1; sh<=4; sh++) {
						add(i*4-4+j,k*4-4+sh,ts*sqrt((x[i][j]-x[k][sh])*(x[i][j]-x[k][sh])+(y[i][j]-y[k][sh])*(y[i][j]-y[k][sh])));
						add(k*4-4+sh,i*4-4+j,ts*sqrt((x[i][j]-x[k][sh])*(x[i][j]-x[k][sh])+(y[i][j]-y[k][sh])*(y[i][j]-y[k][sh])));
					}
				}
			}
		}
		d[a*4-3]=d[a*4-1]=d[a*4-2]=d[a*4]=0;
		q.push(a*4-3);
		q.push(a*4-1);
		q.push(a*4-2);
		q.push(a*4);
		while(!q.empty()) {
			now=q.front();
			//printf("%d\n",now);
			q.pop();
			cur=h[now];
			while(cur!=-1) {
				tmp=f[cur];
				if(d[tmp.to]>d[now]+tmp.w) d[tmp.to]=d[now]+tmp.w,q.push(tmp.to);
				cur=tmp.z;
			}
		}
		printf("%.1lf\n",min(min(d[b*4-3],d[b*4-2]),min(d[b*4-1],d[b*4])));
	}
}
posted @ 2020-03-30 13:31  275307894a  阅读(35)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end