【JZOJ A组】【NOIP2019模拟】最短路(tiring)

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

见下载

Sample Output

见下载

Data Constraint

在这里插入图片描述

思路

观察边权的变化,发现变三次一个周期

所以把一个点拆成三个,跑dijkstra即可

注意!!!!不要跑spfa!!!
不然会和我一样TLE!!!

代码

#include<bits/stdc++.h>
#define add(x,y) to[++top]=y,nx[top]=fir[x],fir[x]=top
#define calc(x,e) (e==0?x:(e==1?(1.0/(x-1)):(1.0*(x-1)/x)))
#define N 300077
using namespace std;
int n,m,to[N+N],nx[N+N],fir[N/3],top,que[N*60],h,t;
bool vis[N];
double f[N],v[N+N][3];
unsigned int ky=2333333;
int nw(int n)
{
	ky^=ky<<15;ky^=ky>>17;ky^=ky>>3;return ky%n;
}
int main()
{
	freopen("tiring.in","r",stdin);
	freopen("tiring.out","w",stdout);
	scanf("%d %d",&n,&m);
	for(int i=1; i<=m; i++)
	{
		int x,y,e;scanf("%d %d %d",&x,&y,&e);
		--y;--x;
		add(y,x);v[top][0]=calc(e,0);v[top][1]=calc(e,1);v[top][2]=calc(e,2);
		add(x,y);v[top][0]=calc(e,0);v[top][1]=calc(e,1);v[top][2]=calc(e,2);
	}
	for(int i=0; i<n*3; i++)f[i]=1e18;
	f[0]=0;
	for(vis[que[t=1]=0]=1;h^t;)
	{
		++h; int p=nw(t-h+1);
		if(f[que[h]]>f[que[h+p]])swap(que[h],que[h+p]);
		if(h<t&&f[que[h+1]]<f[que[h]])swap(que[h],que[h+1]);
		int x=que[h]/3,q=que[h]%3,Q=(q+1)%3;
		for(int i=fir[x]; i; i=nx[i])
		{
			int y=to[i];double F=f[x*3+q]+v[i][q];
			if(F<f[y*3+Q])
			{
				f[y*3+Q]=F;
				if(!vis[y*3+Q])
				{
					vis[que[++t]=y*3+Q]=1;
					if(f[que[t]]<f[que[h+1]])swap(que[h+1],que[t]);
				}
			}
		}vis[x*3+q]=0;
	}
	double ans=min(f[n*3-3],min(f[n*3-2],f[n*3-1]));
	if(ans>1e14)printf("chu ti ren shi zhi zhang");else printf("%.3lf",ans);
}
发布了703 篇原创文章 · 获赞 392 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/Eric1561759334/article/details/100807294
今日推荐