• HDU 3790 最短路径问题


    最短路径问题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 30385    Accepted Submission(s): 8985


    Problem Description
    给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
     
    Input
    输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
    (1<n<=1000, 0<m<100000, s != t)
     
    Output
    输出 一行有两个数, 最短距离及其花费。
     
    Sample Input
    3 2 1 2 5 6 2 3 4 5 1 3 0 0
     
    Sample Output
    9 11
     
    思路:也是一道入门的最短路问题,之前一直wa了,后面才想到某一条路径可能会重复出现,判断下取最小的就好了。
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int M = 1009;
    int n,m,vis[M],dist[M],ans[M],minn,g[M][M],i,j,u,a,b,d,p,s,e,v[M][M];
    void dij(){
        for(i=0;i<=n;i++){
            dist[i] = INF;
            vis[i] = 0;
        }
        dist[s] = 0;
        ans[s] = 0;
        int n1 = n;
        while(n1--){
            int minn = INF;
            for(i=1;i<=n;i++){
                if(!vis[i]&&minn>dist[i]){
                    minn = dist[i]; u = i;
                }
            }
            vis[u] = 1;
            for(i=1;i<=n;i++){
                if(!vis[i]&&dist[i]>dist[u]+g[u][i]){
                    dist[i] = dist[u] + g[u][i];
                    ans[i] = ans[u] + v[u][i];
                }
                else if(!vis[i]&&dist[i]==dist[u]+g[u][i]){
                    ans[i] = min(ans[i],ans[u]+v[u][i]);
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        while(cin>>n>>m){
            memset(g,INF,sizeof(g));
            memset(v,INF,sizeof(v));
            if(n==0&&m==0) break;
            for(i=0;i<=n;i++){
                for(j=0;j<=n;j++){
                    if(i==j) g[i][j] = 0;
                    else g[i][j] = INF;
                }
            }
            for(i=1;i<=m;i++){
                cin>>a>>b>>d>>p;
                if(g[a][b]>=d){
                g[a][b] = g[b][a] = d;
                v[a][b] = v[b][a] = p;
                }
            }
            cin>>s>>e;
                dij();
                cout<<dist[e]<<" "<<ans[e]<<endl;
        }
    }
  • 相关阅读:
    Qt QString转char[]数组
    Qt 如何使窗体初始最大化
    Qt 子窗口监听主窗口信号
    SQL SERVER 日志已满的处理方法 (转)
    C#中的sleep()和wait()
    C#中的sleep()和wait()
    C# 生成1100的随机数
    C# 生成1100的随机数
    gridcontrol 添加行号
    gridcontrol 添加行号
  • 原文地址:https://www.cnblogs.com/kls123/p/7773233.html
Copyright © 2020-2023  润新知