• 《挑战程序设计竞赛》2.5 最短路 AOJ0189 2249 2200 POJ3255 2139 3259 3268(5)


    AOJ0189

    http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0189

    题意

    求某一办公室到其他办公室的最短距离。
    多组输入,n表示n条关系,下面n次每次输入 x y d表示x到y的距离是d。需要注意的是n没有给定,需要根据输入来求。
    输出办公室的编号和距离。

    思路

    任意两点之间的最短距离用floyd算法比较合适。

    代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N = 10;
    const int M = 10;
    const int INF = 0x3f3f3f3f;
    
    int d[N][N];
    int n;
    
    void input()
    {
        for (int i = 0; i < N; i ++)
            fill(d[i], d[i]+N, INF);
        int m;
        cin >> m;
        n = 0;
        while ( m-- ) {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            d[a][b] = d[b][a] = c;
            n = max(max(n, a+1), b+1);
        }
    }
    
    void solve()
    {
        for (int k = 0; k < n; k ++) {
            for (int i = 0; i < n; i ++) {
                for (int j = 0; j < n; j ++) {
                    d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
                }
            }
        }
    
        int sum, msum = INF;
        int id = 0;
        for (int i = 0; i < n; i ++) {
            sum = 0;
            for (int j = 0; j < n; j ++) {
                if (i == j) continue;
                sum += d[i][j];
            }
            if (sum < msum) {
                msum = sum;
                id = i;
            }
        }
        printf("%d %d
    ", id, msum);
    }
    
    int main(void)
    {
        int m;
        while ( cin >> m && m ) {
            for (int i = 0; i < N; i ++)
                fill(d[i], d[i]+N, INF);
            n = 0;
            while ( m-- ) {
                int a, b, c;
                scanf("%d%d%d", &a, &b, &c);
                d[a][b] = d[b][a] = c;
                n = max(max(n, a+1), b+1);
            }
            solve();
        }
        return 0;
    }

    POJ2139

    http://poj.org/problem?id=2139

    题意

    奶牛们最近要拍电影了……
    1、若两个的奶牛一起工作则,他们相互的度(degrees)为;
    2、若两只奶牛a、b不一起工作,但与另有一只奶牛都和他们工作,则a、b的相互的度为2。
    求奶牛的与其他奶牛的度的平均值的100的整数。

    思路

    本题题意可以变换的理解为如果N个点在一个集合中,则这些点之间的距离为1。然后由此建立一个无向图。在这N个点中,每一个点与其他的所有点都有一个连接的路径长度,将这些长度都加起来,然后除以N-1,就求出了平均长度。题目所求为这些平均长度中的最小值,然后将最小值乘以100输出。
    由于所有点到其他点的距离都要求,这个题用floyd算法最为合适,但也可用dijkstra算法计算N次求解,其中dij算法的实现又分使用邻接矩阵和邻接表两种实现方式。
    因此解法有三种,我都实现了。

    代码1(floyd)

    Source Code
    
    Problem: 2139       User: liangrx06
    Memory: 368K        Time: 32MS
    Language: C++       Result: Accepted
    Source Code
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N = 300;
    const int INF = 0x3f3f3f3f;
    
    int d[N+1][N+1];
    int n;
    
    void input()
    {
        int m;
        cin >> n >> m;
        for (int i = 1; i <= n; i ++)
            fill(d[i]+1, d[i]+1+n, INF);
        while ( m-- ) {
            int k, movie[N];
            cin >> k;
            for (int i = 0; i < k; i++) {
                scanf("%d", &movie[i]);
            }
            for (int i = 0; i < k; i++) {
                for (int j = i+1; j < k; j++) {
                    d[movie[i]][movie[j]] = 1; 
                    d[movie[j]][movie[i]] = 1; 
                }
            }
        }
    }
    
    void solve()
    {
        for (int k = 1; k <= n; k ++) { 
            for (int i = 1; i <= n; i ++) {
                for (int j = 1; j <= n; j ++) {
                    d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
                }
            }
        }
    
        int sum;
        int msum = INF;
        for (int i = 1; i <= n; i ++) {
            sum = 0;
            for (int j = 1; j <= n; j ++) {
                if (i == j) continue;
                sum += d[i][j];
            }
            msum = (sum < msum) ? sum : msum;
        }
        double res = (double)msum / (n-1) * 100;
        printf("%d
    ", (int)res);
    }
    
    int main(void)
    {
        input();
        solve();
        return 0;
    }

    代码2(dijkstra-邻接矩阵)

    Source Code
    
    Problem: 2139       User: liangrx06
    Memory: 336K        Time: 16MS
    Language: C++       Result: Accepted
    Source Code
    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    const int N = 300;
    const int INF = 0x3f3f3f3f;
    
    int cost[N+1][N+1];
    int d[N+1];
    bool v[N+1];
    int n;
    
    void input()
    {
        int m;
        cin >> n >> m;
        for (int i = 1; i <= n; i ++)
            fill(cost[i]+1, cost[i]+1+n, INF);
        while ( m-- ) {
            int k, movie[N];
            cin >> k;
            for (int i = 0; i < k; i++) {
                scanf("%d", &movie[i]);
            }
            for (int i = 0; i < k; i++) {
                for (int j = i+1; j < k; j++) {
                    cost[movie[i]][movie[j]] = 1;
                    cost[movie[j]][movie[i]] = 1;
                }
            }
        }
    }
    
    int dijkstra(int s)
    {
        fill(d+1, d+1+n, INF);
        fill(v+1, v+1+n, false);
        d[s] = 0;
    
        while ( true ) {
            int u = -1;
            for (int i = 1; i <= n; i ++) {
                if ( !v[i] && ( u == -1 || d[i] < d[u] ) )
                    u = i;
            }
            if ( u == -1 )
                break;
            v[u] = true;
            for (int i = 1; i <= n; i ++) {
                if ( !v[i] && d[u] + cost[u][i] < d[i] )
                    d[i] = d[u] + cost[u][i];
            }
        }
    
        int sum = 0;
        for (int i = 1; i <= n; i ++)
            sum += d[i];
        return sum;
    }
    
    void solve()
    {
        int sum;
        int msum = INF;
        for (int i = 1; i <= n; i ++) {
            sum = dijkstra(i);
            msum = (sum < msum) ? sum : msum;
        }
        double res = (double)msum / (n-1) * 100;
        printf("%d
    ", (int)res);
    }
    
    int main(void)
    {
        input();
        solve();
        return 0;
    }

    代码3(dijkstra-邻接表)

    Source Code
    
    Problem: 2139       User: liangrx06
    Memory: 236K        Time: 32MS
    Language: C++       Result: Accepted
    Source Code
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <vector>
    using namespace std;
    
    const int N = 300;
    const int INF = 0x3f3f3f3f;
    
    struct Edge {
        int to, cost;
        Edge(int t, int c) {
            to = t;
            cost = c;
        }
    };
    typedef pair<int, int> P;
    
    int n;
    int d[N+1];
    vector<Edge> G[N+1];
    
    void input()
    {
        int m;
        cin >> n >> m;
        while ( m-- ) {
            int k, movie[N];
            cin >> k;
            for (int i = 0; i < k; i++) {
                scanf("%d", &movie[i]);
            }
            for (int i = 0; i < k; i++) {
                for (int j = i+1; j < k; j++) {
                    G[movie[i]].push_back(Edge(movie[j], 1));
                    G[movie[j]].push_back(Edge(movie[i], 1));
                }
            }
        }
    }
    
    int dijkstra(int s) {
        priority_queue<P, vector<P>, greater<P> > que;
        fill(d+1, d+1+n, INF);
        d[s] = 0;
        que.push(P(0, s));
    
        while ( !que.empty() ) {
            P p = que.top(); que.pop();
            int u = p.second;
            if (d[u] < p.first) continue;
            for (int i = 0; i < G[u].size(); i++) {
                Edge e = G[u][i];
                if ( d[e.to] > d[u] + e.cost) {
                    d[e.to] = d[u] + e.cost;
                    que.push(P(d[e.to], e.to));
                }
            }
        }
    
        int sum = 0;
        for (int i = 1; i <= n; i ++)
            sum += d[i];
        return sum;
    }
    
    void solve()
    {
        int sum;
        int msum = INF;
        for (int i = 1; i <= n; i ++) {
            sum = dijkstra(i);
            msum = (sum < msum) ? sum : msum;
        }
        double res = (double)msum / (n-1) * 100;
        printf("%d
    ", (int)res);
    }
    
    int main(void)
    {
        input();
        solve();    
        return 0; 
    }
  • 相关阅读:
    局部变量的认识
    179一个错误的认识
    (jmeter笔记) websocket接口测试
    (jmeter笔记)聚合报告分析
    (jmeter笔记)模拟用户各种场景压测
    (linux笔记)开放防火墙端口
    (jmeter笔记)导出响应内容的网络文件
    (jmeter笔记)jmeter导出excel,中文显示乱码
    (jmeter笔记)jmeter监控服务器资源
    (Jmeter笔记)jmeter连接数据库(mysql)
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083759.html
Copyright © 2020-2023  润新知