zoukankan      html  css  js  c++  java
  • 最短路,Dijkstra,SPFA——hdu1535

    题目链接

    今天集训学长没有给负环的题,所以一下子全都用Dijkstra做了,SPFA都没练习到,所以专门把这道不卡SPFA的题拿来练练

    题目含义

    求1到其他点的最短距离之和,加上其他点到1的最短距离之和

    题目分析

    求1到其他点的最短距离之和,也就是单源最短路径,Dijkstra和SPFA应该都行

    而其他点到1的最短距离之和,实际上还是求的1到其他点的距离,不过由于路径两个方向的长度不一样,所以反向建树就好了

    题目代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    const int maxn=1e6+7;
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    int head[maxn],dis[maxn];
    int tot,u[maxn],v[maxn],w[maxn];
    bool vis[maxn];
    LL ans;
    int t,n,m;
    struct edge{
        int to,w,next;
    }e[maxn];
    struct node{
        int pos,dis;
        bool operator<(const node &x)const{
            return dis>x.dis;
        }
    };
    void add(int u,int v,int w){
        e[tot].to=v;
        e[tot].w=w;
        e[tot].next=head[u];
        head[u]=tot++;
    }
    void init(){
        tot=0;
        memset(dis,INF,sizeof(dis));
        memset(head,-1,sizeof(head));
        memset(vis,false,sizeof(vis));
    }
    void Dijkstra(){
        dis[1]=0;
        priority_queue<node>q;
        q.push((node){1,0});
        while(!q.empty()){
            node temp=q.top();q.pop();
            int u=temp.pos;
            if(vis[u])continue;
            vis[u]=true;
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].w){
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v])q.push((node){v,dis[v]});
                }
            }
        }
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            ans=0;
            init();
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&u[i],&v[i],&w[i]);
                add(u[i],v[i],w[i]);
            }
            Dijkstra();
            for(int i=2;i<=n;i++)
                ans+=dis[i];
            init();
            for(int i=1;i<=m;i++){
                add(v[i],u[i],w[i]);
            }
            Dijkstra();
            for(int i=2;i<=n;i++)
                ans+=dis[i];
            printf("%lld
    ",ans);
        }
        return 0;
    }
    Dijkstra做法

    真的是Dijkstra做多了,一遍就过了

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    const int maxn=1e6+7;
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    int head[maxn],dis[maxn],num[maxn];
    bool vis[maxn];
    LL ans;
    int t,n,m,tot,u[maxn],v[maxn],w[maxn];
    struct edge{
        int to,w,next;
    }e[maxn];
    void add(int u,int v,int w){
        e[tot].to=v;
        e[tot].w=w;
        e[tot].next=head[u];
        head[u]=tot++;
    }
    void init(){
        tot=0;
        memset(head,-1,sizeof(head));
        memset(vis,false,sizeof(vis));
        memset(dis,INF,sizeof(dis));
        memset(num,0,sizeof(num));
    }
    bool SPFA(){
        queue<int>q;
        dis[1]=0;num[1]++;vis[1]=true;
        q.push(1);
        while(!q.empty()){
            int u=q.front();q.pop();
            vis[u]=false;
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].to;
                if(dis[v]>dis[u]+e[i].w){
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v]){
                        vis[v]=true;
                        num[v]++;
                        q.push(v);
                        if(num[v]>n)return false;
                    }
                }
            }
        }
        return true;
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            ans=0;
            init();
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&u[i],&v[i],&w[i]);
                add(u[i],v[i],w[i]);
            }
            SPFA();
            for(int i=2;i<=n;i++)
                ans+=dis[i];
            init();
            for(int i=1;i<=m;i++){
                add(v[i],u[i],w[i]);
            }
            SPFA();
            for(int i=2;i<=n;i++)
                ans+=dis[i];
            printf("%lld
    ",ans);
        }
        return 0;
    }
    SPFA做法

    我果然写的不熟练,照着模板写的

    还得再练练

  • 相关阅读:
    2-10 案例4:像素读取写入
    2-8 案例3:不同图片质量保存
    2-7 案例2:图片写入
    Linux文件操作实用笔记
    Linux文件操作实用笔记
    Linux 文件系统基础
    Linux 文件系统基础
    一篇故事讲述了计算机网络里的基本概念:网关,DHCP,IP寻址,ARP欺骗,路由,DDOS等...
    一篇故事讲述了计算机网络里的基本概念:网关,DHCP,IP寻址,ARP欺骗,路由,DDOS等...
    30 个与程序猿有关的成语
  • 原文地址:https://www.cnblogs.com/helman/p/11278463.html
Copyright © 2011-2022 走看看