《挑战程序设计竞赛》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\n", 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\n", (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\n", (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\n", (int)res);
}

int main(void)
{
    input();
    solve();    
    return 0; 
}

posted on 2015-12-21 23:09  梁山伯  阅读(375)  评论(0编辑  收藏  举报

导航