[LG] P2384 最短路
阿新 • • 發佈:2020-08-02
題意:求乘積意義下的最短路,答案為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; }