JZOJ A基[] [] NOIP2019アナログ最短(疲れます)

説明

ここに画像を挿入説明

入力

ここに画像を挿入説明

出力

ここに画像を挿入説明

サンプル入力

ダウンロードを参照してください。

サンプル出力

ダウンロードを参照してください。

データ制約

ここに画像を挿入説明

思考

観察の右側の変化は、その3倍の周期の変更を発見しました

そのため、ポイントが3分割され、ダイクストラを実行することができます

注意!spfaを実行しないでください!
または意志I 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