洛谷 P2384 最短路
题目原地址 https://www.luogu.org/problem/P2384
- 题目描述
给定n个点的带权有向图,求从1到n的路径中边权之积最小的简单路径。 - 输入格式
第一行读入两个整数n,m,表示共n个点m条边。 接下来m行,每行三个正整数x,y,z,表示点x到点y有一条边权为z的边。 - 输出格式
输出仅包括一行,记为所求路径的边权之积,由于答案可能很大,因此狗哥仁慈地让你输出它模9987的余数即可。 - 数据限制
对于20%的数据,n<=10。
对于100%的数据,n<=1000,m<=1000000。边权不超过10000。 - 输入输出样例
- 输入
3 3
1 2 3
2 3 3
1 3 10
-输出
9
整体思路:邻接表+SPFA直接带走
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
int n,m,head[320000],cnt,dis[150000],vis[150000];
struct node{
int next;
int from,to,dis;
}s[3200000];
void add_edge(int from,int to,int dis){
s[++cnt].next=head[from];
s[cnt].to=to;
s[cnt].dis=dis;
head[from]=cnt;
}
int main(){
cin>>n>>m;
memset(head,0,sizeof(head));
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
add_edge(a,b,c);
add_edge(b,a,c);
}
vis[1]=1,dis[1]=0;
queue<int>Q;
Q.push(1);
while(!Q.empty()){
int u=Q.front();
Q.pop();
vis[u]=0;
for(int i= head[u];i;i=s[i].next){
int to=s[i].to;
int di=s[i].dis;
if(dis[to]>dis[u] + di){
dis[to]=dis[u]+di;
if(!vis[to]){
vis[to]=1;
Q.push(to);
}
}
}
}
cout<<dis[n]%9987;
return 0;
}