题目描述
给定n个点的带权有向图,求从1到n的路径中边权之积最小的简单路径。
输入输出格式
输入格式:
第一行读入两个整数n,m,表示共n个点m条边。 接下来m行,每行三个正整数x,y,z,表示点x到点y有一条边权为z的边。
输出格式:
输出仅包括一行,记为所求路径的边权之积,由于答案可能很大,因此狗哥仁慈地让你输出它模9987的余数即可。
输入样例:
3 3
1 2 3
2 3 3
1 3 10
输出:
9
分析:
将起点到终点的所有路径相乘并作为答案,根据Dijkstra的算法思想可以每次贪心贪到当前最短的边再相乘便可以得到答案
这道题只需要将dijkstra的模板修改一下即可作为刚开始学最短路练手还算不错的
如果有什么不明白的那么说明你对dijkstra这个算法不熟练,请移步到我的dijkstra模板博客
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <iomanip> #include <vector> using namespace std; #define in cin #define out cout typedef long long insert; const int N=2e5+200; const int INF=0x3f3f3f3f; insert n,m,x,y,z,dis[N]; bool vis[N]; struct Node { insert to,w; }; vector<struct Node> vt[N]; void inital_value() { for(int i=1;i<=m;i++) { in>>x>>y>>z; struct Node now; now.to=y;now.w=z; vt[x].push_back(now); } memset(dis,INF,sizeof(dis)); dis[1]=1; return; } void dijkstra() { for(int k=1;k<=n;k++) { insert minn=INF,pos; for(int i=1;i<=n;i++) { if(!vis[i]&&dis[i]<minn) minn=dis[i],pos=i; } vis[pos]=true; for(int i=0;i<vt[pos].size();i++) { if(!vis[vt[pos][i].to]&&dis[vt[pos][i].to]>dis[pos]*vt[pos][i].w) dis[vt[pos][i].to]=dis[pos]*vt[pos][i].w; } } return; } int main() { in>>n>>m; inital_value(); dijkstra(); out<<dis[n]%9987; return 0; }