[LG] P2384 最短路

题意:求乘积意义下的最短路,答案为dis取模

乘积,想到取log,把乘法变为加法
这样就可以跑最短路了

但是答案会非常大,log下也不能取模
于是记录路径,倒着回去,用原边权一步一步乘并取模

#include<bits/stdc++.h> 
#include<cmath>
using namespace std;

inline int rd(){
	int ret=0,f=1;char c;
	while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
	return ret*f;	
}

const int MAXN = 1005;
const int M = 1000001;

struct Edge{
	int to,next,w;
	double dw;
}e[M<<1];
int ecnt,head[MAXN];
inline void add(int x,int y,int w){
	e[++ecnt].next = head[x];
	e[ecnt].to = y;
	e[ecnt].dw = log10(w);
	e[ecnt].w = w;
	head[x] = ecnt;	
}

struct Node{
	int id;
	double w;	
	Node(int x=0,double y=0.0){id=x;w=y;}
	bool operator < (const Node &rhs)const{
		return w>rhs.w;
	}
}top;

priority_queue<Node> Q;
int vis[MAXN];
double dis[MAXN];
int pre[MAXN];
double prew[MAXN];
void dij(int st){
	memset(dis,127,sizeof(dis));
	Q.push(Node(st,0));dis[st]=0;
	while(!Q.empty()){
		top=Q.top();Q.pop();
		int mnid=top.id;
		double mn=top.w;
		if(vis[mnid]) continue;
		if(mn!=dis[mnid]) continue;
		vis[mnid]=1;
		for(int i=head[mnid];i;i=e[i].next){
			int v=e[i].to;
			if(dis[v]>mn+e[i].dw){
				dis[v]=mn+e[i].dw;
				Q.push(Node(v,dis[v]));	
				pre[v]=mnid;
				prew[v]=e[i].w;
			}
		}
	}	
}

int m,n;

int main(){
	n=rd();m=rd();
	int x,y,z;
	for(int i=1;i<=m;i++){
		x=rd();y=rd();z=rd();
		add(x,y,z);
	}
	dij(1);
	int cur=n;
	int ans=1;
	while(cur!=1){
		ans*=prew[cur];
		ans%=9987;
		if(ans==0) ans=1;
		cur=pre[cur];
	}
	cout<<ans;
	return 0;	
}
原文地址:https://www.cnblogs.com/ghostcai/p/13418059.html