题目背景
狗哥做烂了最短路,突然机智的考了Bosh一道,没想到把Bosh考住了...你能帮Bosh解决吗?
他会给你100000000000000000000000000000000000%10金币w (不就是 0 吗。。。)
题目描述
给定n个点的带权有向图,求从1到n的路径中边权之积最小的简单路径。 (注意!是求积而不是求和)
输入输出格式
输入格式:
第一行读入两个整数n,m,表示共n个点m条边。 接下来m行,每行三个正整数x,y,z,表示点x到点y有一条边权为z的边。
输出格式:
输出仅包括一行,记为所求路径的边权之积,由于答案可能很大,因此狗哥仁慈地让你输出它模9987的余数即可。
废话当然是一个数了w
//谢fyszzhouzj指正w
对于20%的数据,n<=10。
对于100%的数据,n<=1000,m<=1000000。边权不超过10000。
输入输出样例
说明
好好看一看再写哟w
思路:SPFA 求最短路(同样的板子题) 难度:普及/提高-
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<queue> #define MAXN 1000001 using namespace std; queue<int> q; int n, m; int tot; int dis[MAXN], vis[MAXN]; int to[MAXN], net[MAXN], head[MAXN], cap[MAXN]; void add(int u,int v,int w) { //邻接链表存图 to[++tot] = v; net[tot] = head[u]; head[u] = tot; cap[tot] = w; } void spfa(int x) { //spfa核心代码 for(int i = 1; i <= n; i++) { //初始化 dis[i] = MAXN; vis[i] = 0; } dis[x] = 1; vis[x] = 1; q.push(x); while(!q.empty()) { int y = q.front(); q.pop(); vis[y] = 1; for(int i = head[y]; i; i = net[i]) { int t = to[i]; if(dis[t] > dis[y]*cap[i]) { dis[t] = dis[y]*cap[i]; if(!vis[t]) vis[t] = 1, q.push(t); } } } } int main() { int u, v, w; scanf("%d%d", &n, &m); for(int i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &w); add(u, v, w); } spfa(1); printf("%d", dis[n]%9987); //不要忘记%9987 return 0; }