码迷,mamicode.com
首页 > 其他好文 > 详细

最短路

时间:2018-05-05 15:56:20      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:因此   empty   ace   cto   one   jks   表示   直接   lld   

题目描述

给你一个n个点,m条边的无向图,定义一条路径的化学系数为路径上所有边的积。
请你找出一条1到n的路径,使它的化学系数最小,并输出这个化学系数对998244353取模
后的结果。

输入格式
第一行两个正整数n,m
接下来m行,每行3个正整数u,v,w,表示从u到v有一条边权为w的边

输出格式
一行一个整数ans表示最小的化学系数

样例输入
3 3
1 2 3
2 3 3
1 3 10

 

样例输出
9

 

别看这是边权之积,但是spfa,dijkstra照样能跑。不过因为会爆long long,因此期望得分50.

 

正解:其实这是一道数学题……

高一的我们都学过,loga + logb = log(a * b)。所以对于每一条边,先取一个log,然后跑一遍最短路,最后还原dis就可。

 

小优化:为了避免精度问题,可以直接在计算的时候取log,并记录路径,最后反过来求边权之积。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<vector>
 7 #include<queue>
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn = 2e3 + 5;
11 const int INF = 0x3f3f3f3f;
12 const int mod = 998244353;
13 
14 int n, m;
15 vector<int> v[maxn], c[maxn];
16 bool done[maxn];
17 double dis[maxn];
18 int path[maxn], len[maxn];
19 void spfa(int s)
20 {
21     for(int i = 1; i <= n; ++i) dis[i] = INF;
22     queue<int> q;
23     q.push(s); dis[s] = 0;
24     while(!q.empty())
25     {
26         int now = q.front(); q.pop(); done[now] = 0;
27         for(int i = 0; i < (int)v[now].size(); ++i)
28         {
29             if(dis[now] + log(c[now][i]) < dis[v[now][i]])
30             {
31                 dis[v[now][i]] = dis[now] + log(c[now][i]);
32                 path[v[now][i]] = now; len[v[now][i]] = c[now][i];
33                 if(!done[v[now][i]])
34                 {
35                     q.push(v[now][i]); done[v[now][i]] = 1;
36                 }
37             }
38         }
39     }
40     int x = n;
41     ll ans = 1;
42     while(path[x])
43     {
44         ans *= len[x]; ans %= mod;
45         x = path[x];
46     }
47     printf("%lld\n", ans);
48 }
49 
50 int main()
51 {
52     scanf("%d%d", &n, &m);
53     for(int i = 1; i <= m; ++i)
54     {
55         int a, b, cost; scanf("%d%d%d", &a, &b, &cost);
56         v[a].push_back(b); c[a].push_back(cost);
57         v[b].push_back(a); c[b].push_back(cost);
58     }
59     spfa(1);
60     return 0;
61 }

 

最短路

标签:因此   empty   ace   cto   one   jks   表示   直接   lld   

原文地址:https://www.cnblogs.com/mrclr/p/8994898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!