洛谷 P4779 【模板】单源最短路径(标准版) 题解

题目来源:

https://www.luogu.org/problemnew/show/P4779

题目描述:

 

题目背景

狗哥做烂了最短路,突然机智的考了Bosh一道,没想到把Bosh考住了...你能帮Bosh解决吗?

他会给你100000000000000000000000000000000000%10金币w

题目描述

给定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。

输入输出样例

输入样例#1: 复制

3 3
1 2 3 
2 3 3 
1 3 10

输出样例#1: 复制

9

说明

好好看一看再写哟w

解题思路:

         单源最短路的模板,不过这题数据是精心构造的,我以前很喜欢用spfa,在这题用的时候就崩了,后来想起来,在哪看过spfa的时间复杂度不稳定,最坏的情况是会到o(n^2),所以我赶紧改成了dijsktra+优先队列做了,这样就可以通过了,看来以后时间充裕还是用dij比较好。。

代码:

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<stack>
#include<vector>
#include<cstdio>
#define ll long long
#define inf 1e9+10
using namespace std;
const int maxn=1e5+10;
struct newt
{
    int to,next,val;
}e[2*maxn];
int n,cnt,m,vis[maxn],head[maxn];
int dis[maxn];
priority_queue<pair<ll,int> >q;
void addedge(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].val=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
int main()
{

    memset(head,-1,sizeof(head));
    cnt=0;int S;
    scanf("%d%d%d",&n,&m,&S);
    for(int i=1;i<=n;i++)dis[i]=1e10+10;
    for(int i=1;i<=m;i++)
    {
        int  a,b, w;
        scanf("%d%d%d",&a,&b,&w);
        addedge(a,b,w);
    }
    q.push(make_pair(0,S));
    dis[S]=0;
    while(!q.empty())
    {
        int now=q.top().second;
        q.pop();
        if(vis[now])continue;
        vis[now]=1;
        for(int i=head[now];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            if(dis[v]>dis[now]+e[i].val)
            {
                dis[v]=dis[now]+e[i].val;
                q.push(make_pair(-dis[v],v));
            }
        }
    }
    for(int i=1;i<=n;i++)
        printf("%d ",dis[i]);
    puts("");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/81452113
今日推荐