• hdu 3790 最短路径问题


    最短路径问题

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


    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
     
    Source
     
    思路:此题为最短路径水题,将采用不同算法来进行练习,Floyd运行超时可以理解,第一个算法用cin就超时,hdu是不是对C++有歧视啊?????
    • Dijkstra算法:
    #include<cstdio>
    #include<climits>
    #include<iostream>
    using namespace std;
    int len[1005], mon[1005], vis[1005];
    int mapp[1005][1005], mapd[1005][1005];
    int n, m;
    void dijkstra(int s)
    {
        memset(vis, 0, sizeof(vis));
    
        for (int i = 1; i <= n; i++){
            len[i] = mapd[s][i];
            mon[i] = mapp[s][i];
        }
    
        vis[s] = 1; len[s] = mon[s] = 0;
        for (int i = 1; i < n; i++){
    
            int min = INT_MAX, p = 1;
            for (int j = 1; j <= n; j++){
                if (min > len[j] && vis[j] == 0){
                    min = len[j];
                    p = j;
                }
            }
    
            vis[p] = 1;
            for (int j = 1; j <= n; j++){
                if (len[p] + mapd[p][j] < len[j] && vis[j] == 0){
                    len[j] = len[p] + mapd[p][j];
                    mon[j] = mon[p] + mapp[p][j];
                }
                else if (len[p] + mapd[p][j] == len[j] && vis[j] == 0){
                    if (mon[p] + mapp[p][j] < mon[j])
                        mon[j] = mon[p] + mapp[p][j];
                }
            }
        }
    }
    int main()
    {
    
        while (cin >> n >> m, n&&m){
    
            for (int i = 0; i <= n; i++)
            for (int j = 0; j <= n; j++)
                mapd[i][j] = mapp[i][j] = 999999;
    
    
            for (int i = 0; i < m; i++){
                int a, b, d, p;
                //cin >> a >> b >> d >> p;
                scanf("%d%d%d%d", &a, &b, &d, &p);
    
                if (d < mapd[a][b]) {
                    mapd[a][b] = mapd[b][a] = d;
                    mapp[a][b] = mapp[b][a] = p;
                }
                else if (mapd[a][b] == d&&mapp[a][b] > p){
                    mapp[a][b] = mapp[b][a] = p;
                }
            }
    
            int s, t; cin >> s >> t;
            dijkstra(s);
            cout << len[t] << " " << mon[t] << endl;
        }
        return 0;
    }
    • 不知道叫什么名字的算法:
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int len[1005], mon[1005];
    struct Node{
        int a, b, d, p;
    };
    vector<Node>way;
    int main()
    {
        int n, m;
        while (cin >> n >> m, n&&m){
            way.clear();              //很重要
            for (int i = 0; i < m; i++){
                Node temp;
                //cin >> temp.a >> temp.b >> temp.d >> temp.p;
                scanf("%d%d%d%d", &temp.a, &temp.b, &temp.d, &temp.p);
                way.push_back(temp);
            }
            int s, t; cin >> s >> t;
    
    
            //memset(len, 125, sizeof(len));
            //memset(mon, 125, sizeof(mon));
            for (int i = 0; i <= n; i++){
                len[i] = mon[i] = 999999;
            }
            len[s] = 0; mon[s] = 0;
            int flag = 1;
            while (flag){
                flag = 0;
                for (int i = 0; i < way.size(); i++){
                    int a = way[i].a, b = way[i].b, d = way[i].d, p = way[i].p;
                    if (len[a] + d < len[b]){
                        flag = 1;
                        len[b] = len[a] + d;
                        mon[b] = mon[a] + p;
                    }
                    else if (len[a] + d == len[b] && mon[a] + p < mon[b]){
                        flag = 1;
                        mon[b] = mon[a] + p;
                    }
                    if (len[b] + d < len[a]){
                        flag = 1;
                        len[a] = len[b] + d;
                        mon[a] = mon[b] + p;
                    }
                    else if (len[b] + d == len[a] && mon[b] + p < mon[a]){
                        flag = 1;
                        mon[a] = mon[b] + p;
                    }
    
                }
            }
            cout << len[t] << " " << mon[t] << endl;
        }
        return 0;
    }
    •  Floyd算法:
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int mapd[1005][1005], mapp[1005][1005];
    int main()
    {
    
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++){
            mapp[i][j] = 9999;
            mapd[i][j] = 9999;
        }
        for (int i = 0; i < m; i++){
            int a, b, d, p;
            //cin >> a >> b >> d >> p;
            scanf("%d%d%d%d", &a, &b, &d, &p);
            mapd[a][b] = mapd[b][a] = d;
            mapp[a][b] = mapp[b][a] = p;
            
        }
    
        for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        for (int k = 1; k <= n; k++){
    
            if (mapd[i][k] + mapd[k][j] < mapd[i][j]){
                mapd[i][j] = mapd[i][k] + mapd[k][j];
                mapp[i][j] = mapp[i][k] + mapp[k][j];
            }
            else if (mapd[i][k] + mapd[k][j] == mapd[i][j]){
                if (mapp[i][k] + mapp[k][j] < mapp[i][j])
                    mapp[i][j] = mapp[i][k] + mapp[k][j];
            }
    
        }
    
    
        int s, t;
        while (cin >> s >> t, s&&t){
            cout << mapd[s][t] << " " << mapp[s][t] << endl;
        }
        return 0;
    }

     今天先到这里,感谢昨天前女友送的一箱三只松鼠;

    • bellman-ford算法(虽然没有AC,不知道毛病在哪):
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    using namespace std;
    int n, m;
    typedef struct Edge{
        int a, b, d, p;
    }Edge;
    Edge edge[100005];
    int len[1005], mon[1005];
    bool Bellman_ford(int s)
    {
        for (int i = 1; i <= n; i++){
            len[i] = 9999999;
            mon[i] = 9999999;
        }
        len[s] = mon[s] = 0;
    
        for (int i = 1; i <= n - 1; i++)
        for (int j = 1; j <= m; j++){
            if (len[edge[j].b]>len[edge[j].a] + edge[j].d){
                len[edge[j].b] = len[edge[j].a] + edge[j].d;
                mon[edge[j].b] = mon[edge[j].a] + edge[j].p;
            }
            else if (len[edge[j].b] == len[edge[j].a] + edge[j].d){
                if (mon[edge[j].b]>len[edge[j].a] + edge[j].p)
                    mon[edge[j].b] = mon[edge[j].a] + edge[j].p;
            }
            
            if (len[edge[j].a]>len[edge[j].b] + edge[j].d){
                len[edge[j].a] = len[edge[j].b] + edge[j].d;
                mon[edge[j].a] = mon[edge[j].b] + edge[j].p;
            }
            else if (len[edge[j].a] == len[edge[j].b] + edge[j].d){
                if (mon[edge[j].a]>len[edge[j].b] + edge[j].p)
                    mon[edge[j].a] = mon[edge[j].b] + edge[j].p;
            }
            
        }
        bool flag = true;
        /*
        for (int i = 1; i <= m; i++){
            if (len[edge[i].b] > len[edge[i].a] + edge[i].d){
                flag = false;
                break;
            }
        }
        */
        return flag;
    }
    int main()
    {
        while (cin >> n >> m, n&&m){
    
            for (int i = 1; i <= m; i++)
                scanf("%d%d%d%d", &edge[i].a, &edge[i].b, &edge[i].d, &edge[i].p);
            
            int s, t; cin >> s >> t;
            if (Bellman_ford(s))
                cout << len[t] << " " << mon[t] << endl;
        }
        
        return 0;
    }
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<iostream>
    using namespace std;
    const int MAX = 200002;
    int n, m;
    struct Node{
        int to;
        int cost;
        int mon;
        Node(int a, int b, int c) :to(a), cost(b), mon(c){}
    };
    vector<Node>vec[MAX];
    bool vis[MAX] = { false };
    long dis[MAX], mon[MAX];
    void spfa(int s)
    {
        for (int i = 0; i <= n; i++){
            vis[i] = false;
            dis[i] = INT_MAX;
            mon[i] = INT_MAX;
        }
        dis[s] = mon[s] = 0;
        queue<int>que;
        que.push(s);
        while (!que.empty()){
            int p = que.front();
            que.pop();
            vis[p] = false;
            for (int i = 0; i < vec[p].size(); i++){
                Node no = vec[p][i];
    
                if (dis[no.to]>dis[p] + no.cost){
                    dis[no.to] = dis[p] + no.cost;
                    mon[no.to] = mon[p] + no.mon;
                    if (!vis[no.to]){
                        que.push(no.to);
                        vis[no.to] = true;
                    }
                }
                else if (dis[no.to] == dis[p] + no.cost){
                    if (mon[no.to] > mon[p] + no.mon){
                        mon[no.to] = mon[p] + no.mon;
                        if (!vis[no.to]){
                            que.push(no.to);
                            vis[no.to] = true;
                        }
                    }
                }
            }
        }
        
    }
    int main()
    {
        while (cin >> n >> m, n&&m){
    
            for (int i = 0; i < m; i++){
                int a, b, d, p;
                //cin >> a >> b >> d >> p;
                scanf("%d%d%d%d", &a, &b, &d, &p);
                vec[a].push_back(Node(b, d, p));
                vec[b].push_back(Node(a, d, p));
            }
            int s, t; cin >> s >> t;
            spfa(s);
            cout << dis[t] << " " << mon[t] << endl;
        }
        
        return 0;
    }

     后面两种算法心好累,我要换个水题在试试了,baibaibaibai

     
  • 相关阅读:
    PHP:面向对象学习笔记,重点模拟Mixin(掺入)
    Mybatis Plus 更新
    Mybatis Plus 自定义SQL和分页插件
    Mybatis Plus 查询方法
    Mybatis Plus 快速入门
    Ribbon 负载均衡服务调用
    三个注册中心异同点
    Consul 服务注册与发现
    Spring Boot 集成 Swagger
    Eureka 服务注册与发现
  • 原文地址:https://www.cnblogs.com/zengguoqiang/p/8847063.html
Copyright © 2020-2023  润新知