zoukankan      html  css  js  c++  java
  • 非负权单源最短路

    Description

    给一个 nn 个点 mm 条边的无向图,求 ss 到 tt 的最短路。

    Input

    第一行四个由空格隔开的整数 nn、mm、ss、tt 。

    之后 mm 行,每行三个正整数 u_iui​、v_ivi​、w_iwi​ ,表示一条从 u_iui​ 到 v_ivi​ 长度为 w_iwi​ 的边。

    保证:

    1 leq n leq 25001≤n≤2500 ,1 leq m leq 62001≤m≤6200 ,1 leq u_i, v_i leq n1≤ui​,vi​≤n ,1 leq w_i leq 10 ^ 91≤wi​≤109。

    Output

    一个整数表示从 ss 到 tt 的最短路的长度,数据保证 ss 与 tt 是连通的。

    Sample Input 1 

    7 11 5 4
    2 4 2
    1 4 3
    7 2 2
    3 4 3
    5 7 5
    7 3 3
    6 1 1
    6 3 4
    2 4 3
    5 6 3
    7 2 1

    Sample Output 1

    7

    Source

    LOJ

    https://oi-wiki.org/graph/shortest-path/

    上面是算法讲解;

    如果数据再大一点。

    用Dijkstra

    需要优先队列。

    不会,学一波

    https://oi-wiki.org/ds/stl/priority_queue/

    这里有讲解。

    也可以去看看别人的博客;

    #include <iostream>
    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    #define maxn 2510
    bool inqueen[3001];
    struct Edge{
        int v,cost;
    };
    ll dis[3001],inf=ll(1e18);
    vector<Edge> edge[maxn];
    int main()
    {
        int n,m,s,t,u,v,w;
        scanf("%d %d %d %d",&n,&m,&s,&t);
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&u,&v,&w);
            edge[u].push_back({v,w});
            edge[v].push_back({u,w});
        }
        queue<int>Q;
        for(int i=1;i<=n;i++)
        {
            dis[i]=inf;
        }
        memset(inqueen,false,sizeof(inqueen));
        dis[s]=0;
        Q.push(s);
        inqueen[s]=true;
        while(!Q.empty()){
            int b=Q.front();
            Q.pop();
            //printf("%d
    ",b);
            inqueen[b]=false;
            int size=int(edge[b].size());
            for(int i=0;i<size;i++)
            {
                int v=edge[b][i].v,cost=edge[b][i].cost;
                if(dis[v]>dis[b]+cost){
                    dis[v]=dis[b]+cost;
                    if(!inqueen[v]){
                        Q.push(v);
                        inqueen[v]=true;
                    }
                }
            }
        }
        printf("%lld
    ",dis[t]);
        return 0;
    }
    #include <iostream>
    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    bool inqueen[2510];
    ll dis[2510],inf=ll(1e18);
    int a[2510][2510];
    int main()
    {
        int n,m,s,t,u,v,w;
        scanf("%d %d %d %d",&n,&m,&s,&t);
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d %d",&u,&v,&w);
            a[u][v]=w;
            a[v][u]=w;
        }
        for(int i=1;i<=n;i++)
        {
            dis[i]=inf;
        }
        memset(inqueen,false,sizeof(inqueen));
        dis[s]=0;
        queue<int>Q;
        Q.push(s);
        inqueen[s]=true;
        while(!Q.empty()){
            int b=Q.front();
            Q.pop();
            //printf("%d
    ",b);
            inqueen[b]=false;
            for(int i=1;i<=n;i++)
            {
                if(a[b][i]>0&&dis[i]>dis[b]+a[b][i])
                {
                    dis[i]=dis[b]+a[b][i];
                    if(!inqueen[i])
                    {
                        Q.push(i);
                        inqueen[i]=true;
                    }
                }
            }
        }
        printf("%lld
    ",dis[t]);
        return 0;
    }
    

    一种是邻接矩阵,一种是邻接表

    下面是Dijkstra;

    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    int n,m,s,t;
    typedef long long ll;
    const int N =100001;
    ll dist[N],inf=ll(1e18);
    bool inque[N];
    struct edge
    {
        int v;
        int time;
    };
    struct youxian{
        int index;
        ll dist;
        bool operator<(const youxian &tmp)
        const {
            return dist>tmp.dist;
        }
    };
    vector<edge>e[N];
    ll fun()
    {
        int i;
        for(i=1;i<=n;i++)
        {
            dist[i]=inf;
            inque[i]=false;
        }
        dist[s]=0;
        priority_queue<youxian>Q;
        Q.push({s,0});
        while(!Q.empty()){
            int u=Q.top().index;
            Q.pop();
            if(inque[u]) continue;
            inque[u]=true;
            int size=int (e[u].size());
            for(i=0;i<size;i++){
                int v=e[u][i].v,time=e[u][i].time;
                if(dist[v]>dist[u]+time){
                    dist[v]=dist[u]+time;
                    Q.push({v,dist[v]});
                }
            }
        }
        return dist[t];
    }
    int main()
    {
        int u,v,w;
        scanf("%d %d %d %d",&n,&m,&s,&t);
        for(int i=0;i<m;i++){
            scanf("%d %d %d",&u,&v,&w);
            e[u].push_back({v,w});
            e[v].push_back({u,w});
        }
        printf("%lld
    ",fun());
        return 0;
    }
    
  • 相关阅读:
    第二周总结
    2019春总结作业
    第二次编程总结
    第四周作业
    第十二周作业
    第十一周作业
    第十周作业
    第九周作业
    第八周作业
    第六周作业
  • 原文地址:https://www.cnblogs.com/skyleafcoder/p/12319557.html
Copyright © 2011-2022 走看看