zoukankan      html  css  js  c++  java
  • 最短路经典例题 codevs 1557 热浪

    codevs 1557 热浪

    题目描述:
    德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他们的德克萨斯长角牛吃起来不错,可是他们并不是很擅长生產富含奶油的乳製品。Farmer John此时以先天下之忧而忧,后天下之乐而乐的精神,身先士卒地承担起向德克萨斯运送大量的营养冰凉的牛奶的重任,以减轻德克萨斯人忍受酷暑的痛苦。
    FJ已经研究过可以把牛奶从威斯康星运送到德克萨斯州的路线。这些路线包括起始点和终点先一共经过T(1<=T<=2500)个城镇,方便地标号為1到T。除了起点和终点外地每个城镇由两条双向道路连向至少两个其它地城镇。每条道路有一个通过费用(包括油费,过路费等等)。
    给定一个地图,包含C(1<=C<=6200)条直接连接2个城镇的道路。每条道路由道路的起点Rs,终点Re(1<=Rs<=T;1<=Re<=T),和花费(1<=Ci<=1000)组成。求从起始的城镇Ts(1<=Ts<=T)到终点的城镇Te(1<=Te<=T)最小的总费用。
    输入描述:
    第一行: 4个由空格隔开的整数: T, C, Ts, Te
    第2到第C+1行: 第i+1行描述第i条道路。有3个由空格隔开的整数: Rs, Re和Ci
    输出描述:
    一个单独的整数表示从Ts到Te的最小总费用。数据保证至少存在一条道路。
    样例输入:
    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
    样例输出:
    7
    数据范围及提示:
    5->6->1->4(3+1+3)

    提供三种解法:
    1、Floyed算法

    #include<iostream>
    using namespace std;
    const int maxn=999999;
    int T,C,ts,te;
    int dis[2501][2501],x,y,z;
    int main()
    {
        cin>>T>>C>>ts>>te;
        for(int i=1;i<=T;i++)
          for(int j=1;j<=T;j++)
          dis[i][j]=maxn;
        for(int i=1;i<=C;i++)
        {
            cin>>x>>y>>z;
            dis[x][y]=dis[y][x]=z;
        }
        for(int k=1;k<=T;k++)
          for(int i=1;i<=T;i++)
            if(k!=i)
            for(int j=1;j<=T;j++)
            if(i!=j&&k!=j&&dis[i][j]>dis[i][k]+dis[k][j])
            dis[i][j]=dis[i][k]+dis[k][j];
        cout<<dis[ts][te];
        return 0;
    }

    因为数据太大,会超时!
    总时间耗费: 3309ms
    总内存耗费: 24 MB
    这里写图片描述
    2、Dijkstra算法
    邻接矩阵版

    #include<iostream>
    using namespace std;
    const int maxn=999999;
    int T,C,ts,te;
    int dis[10000],a[2510][2510];//在空间允许的范围内,dis[]数组尽量开大,否则会出错,不知为什么。。。 
    int x,y,z,k,minn;
    bool flag[10000];
    int main()
    {
        cin>>T>>C>>ts>>te;
        for(int i=1;i<=C;i++)
        {
            cin>>x>>y>>z;
            a[x][y]=a[y][x]=z;
            dis[i]=maxn;
        }
        dis[ts]=0;
        for(int i=1;i<=T;i++)
        {
            minn=maxn;
            k=0;
            for(int j=1;j<=T;j++)
            if(!flag[j]&&dis[j]<minn)
            {
                minn=dis[j];
                k=j;
            }
            if(k==0) break;
            flag[k]=true;
            for(int j=1;j<=T;j++)
            if(!flag[j]&&a[k][j]&&dis[j]>dis[k]+a[k][j])
            dis[j]=dis[k]+a[k][j];
        }
        cout<<dis[te];
        return 0;
    }

    总时间耗费: 139ms
    总内存耗费: 20 MB
    这里写图片描述
    邻接链表版

    #include<iostream>
    using namespace std;
    const int maxn=1000001;
    struct node
    {
        int to;
        int w;
        int next;
    }e[maxn];
    int n,m,tot,minn,k,dis[maxn],head[maxn];
    int qi,zhong;
    bool flag[maxn];
    void edd_edge(int u,int v,int w)
    {
        tot++;
        e[tot].to=v;
        e[tot].w=w;
        e[tot].next=head[u];
        head[u]=tot;
    }
    int main()
    {
        int x,y,z;
        cin>>n>>m>>qi>>zhong;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y>>z;
            edd_edge(x,y,z);
            edd_edge(y,x,z);
        }
        for(int i=1;i<=n;i++)
        dis[i]=maxn;
        dis[qi]=0;
        for(int i=1;i<=n;i++)
        {
            minn=maxn;
            k=0;
            for(int j=1;j<=n;j++)
            if(!flag[j]&&minn>dis[j])
            {
                minn=dis[j];
                k=j;
            }
            flag[k]=1;
            for(int j=head[k];j;j=e[j].next)
            if(!flag[e[j].to]&&dis[e[j].to]>dis[k]+e[j].w)
            dis[e[j].to]=dis[k]+e[j].w;
        }
        cout<<dis[zhong];
        return 0;
    }

    总时间耗费: 67ms
    总内存耗费: 492 kB
    这里写图片描述
    3、SPFA算法
    因为使用了邻接矩阵,所以并没有发挥SPFA算法的优势,竟然不如Dijkstra快。。。
    邻接矩阵版

    #include<iostream>
    using namespace std;
    const int maxn=1000000;
    int T,C,ts,te;
    int dis[10000],a[2501][2501];
    int x,y,z,u,team[10001],head,tail=1;
    bool exsit[2501];
    int main()
    {
        cin>>T>>C>>ts>>te;
        for(int i=1;i<=C;i++)
        {
            cin>>x>>y>>z;
            a[x][y]=a[y][x]=z;
            dis[i]=maxn;
        }
        dis[ts]=0;
        team[1]=ts;
        while(head<tail)
        {
            head++;
            u=team[head];
            exsit[u]=false;
            for(int j=1;j<=T;j++)
            if(dis[j]>dis[u]+a[u][j]&&a[u][j])
            {
                dis[j]=dis[u]+a[u][j];
                if(!exsit[j])
                {
                    tail++;
                    team[tail]=j;
                    exsit[j]=true;
                }
            }
        }
        cout<<dis[te];
        return 0;
    }

    总时间耗费: 160ms
    总内存耗费: 20 MB
    这里写图片描述
    邻接链表版

    #include<iostream>
    #include<queue>
    using namespace std;
    const int maxn=1000001;
    struct node
    {
        int to;
        int w;
        int next;
    }e[maxn];
    queue<int> q;
    bool flag[maxn];
    int n,m,qi,zhong,tot,head[maxn],dis[maxn];
    void edd_edge(int u,int v,int w)
    {
        tot++;
        e[tot].to=v;
        e[tot].w=w;
        e[tot].next=head[u];
        head[u]=tot;
    }
    int main()
    {
        int x,y,z;
        cin>>n>>m>>qi>>zhong;
        for(int i=1;i<=m;i++)
        {
            cin>>x>>y>>z;
            edd_edge(x,y,z);
            edd_edge(y,x,z);
        }
        for(int i=1;i<=n;i++)
        dis[i]=maxn;
        dis[qi]=0;
        q.push(qi);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            flag[u]=0;
            for(int j=head[u];j;j=e[j].next)
            if(dis[e[j].to]>dis[u]+e[j].w)
            {
                dis[e[j].to]=dis[u]+e[j].w;
                if(!flag[e[j].to])
                {
                    q.push(e[j].to);
                    flag[e[j].to]=1;
                }
            }
        }
        cout<<dis[zhong];
        return 0;
    }

    总时间耗费: 20ms
    总内存耗费: 488 kB
    这里写图片描述

  • 相关阅读:
    HDU 2089 不要62
    HDU 5038 Grade(分级)
    FZU 2105 Digits Count(位数计算)
    FZU 2218 Simple String Problem(简单字符串问题)
    FZU 2221 RunningMan(跑男)
    FZU 2216 The Longest Straight(最长直道)
    FZU 2212 Super Mobile Charger(超级充电宝)
    FZU 2219 StarCraft(星际争霸)
    FZU 2213 Common Tangents(公切线)
    FZU 2215 Simple Polynomial Problem(简单多项式问题)
  • 原文地址:https://www.cnblogs.com/cax1165/p/6071018.html
Copyright © 2011-2022 走看看