欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

洛谷 P2384 最短路 题解

程序员文章站 2022-07-02 11:42:32
题目链接比较套路的一道题,本题的方法也可以用来做树的最大乘积独立集由于本题需要取模,所以不能直接求最短路我们考虑将每条边取对数,也就是将边权为 www 的边变为 log⁡2w\log_2wlog2​w这样,根据幂的性质,我们就将乘积最短路转化为了普通最短路,证明显然最后记得要把边权变回来输出#include#include#include#include#include...

题目链接

比较套路的一道题,本题的方法也可以用来做树的最大乘积独立集

由于本题需要取模,所以不能直接求最短路
我们考虑将每条边取对数,也就是将边权为 w w w 的边变为 log ⁡ 2 w \log_2w log2w
这样,根据幂的性质,我们就将乘积最短路转化为了普通最短路,证明显然
最后记得要把边权变回来输出

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const long long Maxn=1010,Maxm=1000000+10;
const long long inf=0x3f3f3f3f;
const long long mod=9987;
long long nxt[Maxm],to[Maxm];
long long val[Maxm],head[Maxn];
double len[Maxm],dis[Maxn];
long long dist[Maxn];
bool vis[Maxn];
long long n,m,edgecnt;
struct node{
	long long pos;
	double dis;
	node(long long x,double y)
	{
		pos=x,dis=y;
	}
	bool operator <(const node &x)const
	{
		return x.dis<dis;
	}
};
inline long long read()
{
	long long s=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return s*w;
}
inline void add(long long x,long long y,double c,long long v)
{
	++edgecnt;
	nxt[edgecnt]=head[x];
	to[edgecnt]=y;
	len[edgecnt]=c;
	val[edgecnt]=v;
	head[x]=edgecnt;
}
void dij(long long s)
{
	priority_queue <node> q;
	fill(dis+1,dis+1+n,inf*1.0);
	dis[s]=0.0,dist[s]=1ll,vis[s]=1;
	q.push(node(s,0.0));
	while(q.size())
	{
		long long x=q.top().pos;
		q.pop();
		for(long long i=head[x];i;i=nxt[i])
		{
			long long y=to[i];
			if(dis[y]>dis[x]+len[i])
			{
				dis[y]=dis[x]+len[i];
				dist[y]=(dist[x]*val[i])%mod;
				if(!vis[y])vis[y]=1,q.push(node(y,dis[y]));
			}
		}
	}
}
int main()
{
	n=read(),m=read();
	for(long long i=1;i<=m;++i)
	{
		long long x=read(),y=read(),z=read();
		add(x,y,log2(z),z);
	}
	dij(1);
	printf("%lld\n",dist[n]);
	return 0;
}

本文地址:https://blog.csdn.net/Brian_Pan_/article/details/109246921