【JZOJ6354】最短路(tiring)

description


analysis

  • 显然边权有变化规律\(x,{1\over{x-1}},{x-1\over x},x,...\)

  • 于是把一个点拆成三个点,分别表示步数到除\(3\)\(0,1,2\)的最小值

  • 拆边的话应该也可以,然后跑最短路

  • 我™这辈子都不会再想打SBFA


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<queue>
#define db double
#define MAXN 600005
#define MAXM MAXN*4
#define INF 19260817e20
#define reg register int
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=last[a];i;i=next[i])

using namespace std;

int last[MAXM],next[MAXM],tov[MAXM];
db len[MAXM],dis[MAXN],ans=INF;
bool bz[MAXN];
int n,m,tot;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
inline db min(db x,db y){return x<y?x:y;}
inline void link(int x,int y,db z){next[++tot]=last[x],last[x]=tot,tov[tot]=y,len[tot]=z;}
struct node
{
	int x;db y;
	bool operator <(const node &a)const{return a.y<y;}
};
priority_queue<node>q;
inline void dijkstra()
{
	while (!q.empty())q.pop();
	memset(dis,100,sizeof(dis));
	memset(bz,0,sizeof(bz));
	q.push((node){3,dis[3]=0});
	while (!q.empty())
	{
		node now=q.top();q.pop();
		if (bz[now.x])continue;bz[now.x]=1;
		rep(i,now.x)if (dis[now.x]+len[i]<dis[tov[i]])
		{dis[tov[i]]=dis[now.x]+len[i];if (!bz[tov[i]])q.push((node){tov[i],dis[tov[i]]});}
	}
	ans=min(dis[3*n],min(dis[3*n+1],dis[3*n+2]));
}
int main()
{
	freopen("T2.in","r",stdin);
	//freopen("tiring.in","r",stdin);
	//freopen("tiring.out","w",stdout);
	n=read(),m=read();
	fo(i,1,m)
	{
		int x=read(),y=read(),z=read();
		link(3*x,3*y+1,1.0*z),link(3*x+1,3*y+2,1.0/(z-1.0)),link(3*x+2,3*y,1.0*(z-1)/z),
		link(3*y,3*x+1,1.0*z),link(3*y+1,3*x+2,1.0/(z-1.0)),link(3*y+2,3*x,1.0*(z-1)/z);
	}
	dijkstra();
	if (ans>1e15)printf("chu ti ren shi zhi zhang\n");
	else printf("%.3lf\n",ans);
	return 0;
}
posted @ 2019-09-13 14:06  路人黑的纸巾  阅读(371)  评论(0编辑  收藏  举报