洛谷 P2384 最短路 题解
程序员文章站
2022-07-02 11:42:32
题目链接比较套路的一道题,本题的方法也可以用来做树的最大乘积独立集由于本题需要取模,所以不能直接求最短路我们考虑将每条边取对数,也就是将边权为 www 的边变为 log2w\log_2wlog2w这样,根据幂的性质,我们就将乘积最短路转化为了普通最短路,证明显然最后记得要把边权变回来输出#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
上一篇: Core Java(一)
下一篇: 微信小程序实现拼图游戏