列表

详情


AB15. 【模板】单源最短路2

描述

给你一个无向图,图中包含 5000 个点 m 个边,任意两个点之间的距离是 w ,无重边或自环。请求出1号点到n号点的最短距离。

注意:图中可能存在孤立点,即存在点与任意点都没有边相连

如果1号点不能到达n号点,输出-1.


输入描述

第一行两个整数n和m,表示图的点和边数。
接下来m行,每行三个整数u,v, w,表示u到v有一条无向边, 长度为w。

输出描述

输出一行,表示1到n的最短路,如不存在,输出-1.

示例1

输入:

4 4
1 2 3
2 4 7
3 4 5
3 1 3

输出:

8

示例2

输入:

4 3
1 2 5
2 3 3
3 1 3

输出:

-1

说明:

1号点不能到4号点。

原站题解

C++ 解法, 执行用时: 20ms, 内存消耗: 1676KB, 提交时间: 2022-05-25

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef pair<int ,int > PII;
const int N = 5010,M = 100010;
int h[N],e[M],ne[M],idx;
int w[M];
int dist[N];
bool st[N];
int n,m;
void add(int a,int b,int c){
    e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx++;
    e[idx] = a,ne[idx] = h[b],w[idx] = c,h[b] = idx++;
}
int  dijkstra(){
    memset(dist,0x3f,sizeof(dist));
    dist[1] = 0;
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    heap.push({0,1});
    while(heap.size()){
        int distance = heap.top().first;
        int ver = heap.top().second;
        heap.pop();
        if(st[ver]) continue;
        st[ver] = true;
        for(int i = h[ver];i != -1;i = ne[i]){
            int j = e[i];
            if(dist[j] > distance + w[i]){
                dist[j] = distance + w[i];
                heap.push({dist[j],j});
            }
        }
    }
    if(dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}
int main(){
    memset(h,-1,sizeof(h));
    scanf("%d%d",&n,&m);
    while(m--){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    int t = dijkstra();
    printf("%d",t);
    return 0;
    
}

C++ 解法, 执行用时: 22ms, 内存消耗: 1708KB, 提交时间: 2022-05-13

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

struct Edge {
    int u, v;
    
    Edge(int u = 0, int v = 0): v(v), u(u) {}
};

struct Node {
    int x, d;
    
    Node(int x = 0, int d = 0): x(x), d(d) {}
    bool operator <(const Node& o) const {
        return d > o.d;
    }
};

int n = 0, m = 0;
int d[5009];
Edge edge[100009];
int first[5009], next1[100009];
bool vis[5009];

void dij(int s) {
    memset(d, -1, sizeof(d));
    memset(vis, 0, sizeof(vis));
    d[s] = 0;
    priority_queue<Node> pq;
    pq.push(Node(s, 0));
    while(!pq.empty()) {
        Node u = pq.top(); pq.pop();
        int x = u.x;
        if(vis[x]) continue;
        vis[x] = true;
        for(int i = first[x]; i != -1; i = next1[i]) {
            Edge& e = edge[i];
            if(!vis[e.u] && (d[e.u] == -1 || d[e.u] > d[x] + e.v)) {
                d[e.u] = d[x] + e.v;
                pq.push(Node(e.u, d[e.u]));
            }
        }
    }
}



int main() {
    scanf("%d%d", &n, &m);
    memset(first, -1, sizeof(first));
    for(int i = 0; i < m; i++) {
        int a = 0, b = 0, v = 0;
        int t = i << 1;
        scanf("%d%d%d", &a, &b, &v);
        edge[t] = Edge(b, v);
        edge[t|1] = Edge(a, v);
        next1[t] = first[a];
        first[a] = t;
        next1[t|1] = first[b];
        first[b] = t|1;
    }
    dij(1);
    printf("%d\n", d[n]);
    return 0;
}

C++ 解法, 执行用时: 22ms, 内存消耗: 1804KB, 提交时间: 2022-04-11

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

struct Edge {
    int u, v;
    
    Edge(int u = 0, int v = 0): v(v), u(u) {}
};

struct Node {
    int x, d;
    
    Node(int x = 0, int d = 0): x(x), d(d) {}
    bool operator <(const Node& o) const {
        return d > o.d;
    }
};

int n = 0, m = 0;
int d[5009];
Edge edge[100009];
int first[5009], next1[100009];
bool vis[5009];

void dij(int);

int main() {
    scanf("%d%d", &n, &m);
    memset(first, -1, sizeof(first));
    for(int i = 0; i < m; i++) {
        int a = 0, b = 0, v = 0;
        int t = i << 1;
        scanf("%d%d%d", &a, &b, &v);
        edge[t] = Edge(b, v);
        edge[t|1] = Edge(a, v);
        next1[t] = first[a];
        first[a] = t;
        next1[t|1] = first[b];
        first[b] = t|1;
    }
    dij(1);
    printf("%d\n", d[n]);
    return 0;
}

void dij(int s) {
    memset(d, -1, sizeof(d));
    memset(vis, 0, sizeof(vis));
    d[s] = 0;
    priority_queue<Node> pq;
    pq.push(Node(s, 0));
    while(!pq.empty()) {
        Node u = pq.top(); pq.pop();
        int x = u.x;
        if(vis[x]) continue;
        vis[x] = true;
        for(int i = first[x]; i != -1; i = next1[i]) {
            Edge& e = edge[i];
            if(!vis[e.u] && (d[e.u] == -1 || d[e.u] > d[x] + e.v)) {
                d[e.u] = d[x] + e.v;
                pq.push(Node(e.u, d[e.u]));
            }
        }
    }
}

C++ 解法, 执行用时: 23ms, 内存消耗: 1792KB, 提交时间: 2022-07-19

#include <bits/stdc++.h>
using namespace std;


int n,m;
typedef pair<int,int> pii;


const int N=5e3+10,M=5e4*2+10;
int h[N],e[M],ne[M],w[M],idx;
int dist[N];
bool st[N];

void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}


int dijkstra()
{
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    priority_queue<pii,vector<pii>,greater<pii>> heap;
    heap.push({0,1});
    while(heap.size())
    {
        auto t=heap.top();
        heap.pop();
        int ver=t.second,distance=t.first;
        if(st[ver]==1)
            continue;
        st[ver]=1;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>distance+w[i])
            {
                dist[j]=distance+w[i];
                heap.push({dist[j],j});
            }
        }
    }
    if(dist[n]==0x3f3f3f3f)
        return 0;
    else 
        return 1;
}
int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof h);

    while(m--)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w),add(v,u,w);

    }
    int k=dijkstra();
    if(k)
        printf("%d\n",dist[n]);
    else 
        cout<<"-1"<<endl;
    return 0;
}

C++ 解法, 执行用时: 23ms, 内存消耗: 2636KB, 提交时间: 2022-04-26

#include<bits/stdc++.h>
using namespace std;
#define maxn 5001
#define INF 0x3f3f3f3f
struct HeadNode
{
    int d,u;
    HeadNode(int d,int u):d(d),u(u){}
    bool operator < (const HeadNode &tmp)const
    {
        return d > tmp.d;
    }
};

struct edge
{
    int u,v,w;
    edge(int u,int v,int w):u(u),v(v),w(w){}
};

struct dijkstra
{
    int n,m;
    vector<edge> edges;
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    void init()
    {
        this->n = 5000;
        for(int i =0;i<=5000;i++)G[i].clear();
        edges.clear();
        
    }
    void addedge(int u,int v, int w)
    {
        edges.push_back(edge(u,v,w));
        int index = edges.size();
        G[u].push_back(index-1);
    }
    void dij(int s)
    {
        priority_queue<HeadNode> q;
        for(int i =1;i<=n;i++)d[i]=INF;
        d[s]=0;
        memset(vis, 0, sizeof vis);
        q.push(HeadNode(0,s));
        while(!q.empty())
        {
            HeadNode x = q.top();
            q.pop();
            int u = x.u;
            if(vis[u])continue;
            vis[u]=true;
            for(int i =0;i<G[u].size();i++)
            {
                edge e = edges[G[u][i]];
                if(d[e.v] > d[u]+e.w)
                {
                    d[e.v] = d[u]+e.w;
                    q.push(HeadNode(d[e.v],e.v));
                }
            }
        }
    }
       
}dij;
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    dij.init();
    int u,v,w;
    for(int i =0;i<m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        dij.addedge(u, v, w);
        dij.addedge(v, u, w);
    }
    dij.dij(1);
    if(dij.d[n]==0x3f3f3f3f)printf("-1\n");
    else printf("%d\n",dij.d[n]);
    return 0;
}

上一题