最短路 2016.9.1

1、UVa 10048 Audiophobia

参考:http://blog.csdn.net/shuangde800/article/details/7985085

题意:
c1到c2的每条路径的声强为这条路径所包含的边的最大权值
求c1到c2的声强最小的一条路径的声强

解题思路:
Floyd变形

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 100 + 10;
int Graph[maxn][maxn];
int C, S, Q;

void Floyd(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif
    int Case = 0;
    while (scanf("%d%d%d", &C, &S, &Q) != EOF && !(C == 0 && S == 0 && Q == 0)) {
        for (int i = 1; i <= C; ++i) {
            for (int j = 1; j <= C; ++j) {
                if (i == j) {
                    Graph[i][j] = 0;
                } else {
                    Graph[i][j] = INF;
                }
            }
        }
        int c1, c2, d;
        for (int i = 0; i < S; ++i) {
            scanf("%d%d%d", &c1, &c2, &d);
            Graph[c1][c2] = Graph[c2][c1] = d;
        }
        Floyd();
        ++Case;
        if (Case > 1) {
            printf("\n");
        }
        printf("Case #%d\n", Case);
        for (int i = 0; i < Q; ++i) {
            scanf("%d%d", &c1, &c2);
            if (Graph[c1][c2] != INF) {
                printf("%d\n", Graph[c1][c2]);
            } else {
                printf("no path\n");
            }
        }
    }
    return 0;
}

void Floyd(void)
{
    for (int k = 1; k <= C; ++k) {
        for (int i = 1; i <= C; ++i) {
            for (int j = 1; j <= C; ++j) {
                Graph[i][j] = min(Graph[i][j], max(Graph[i][k], Graph[k][j]));
            }
        }
    }
}

2、POJ 1135 Domino Effect

参考:http://www.cnblogs.com/liuxueyang/archive/2013/05/05/3060536.html

题意;

计算多米诺骨牌全部倒下需要的时间以及最后倒的位置


解题思路:

Dijkstra 求出每 i 个骨牌倒下需要的时间 dis[i]

如果最后倒在端点处,只要求出 max_dis 就可以了

如果倒在两个端点之间,那么需要求出 max_((dis[i] + dis[j] + Graph[i][j]) / 2.0) (Graph[i][j] != INF)

我们只要比较 这两个最大值就可以确定最后倒在哪里


注意:用 printf 输出用 %.1f,不要用 %.1lf, 否则会 wa(以前听说 %lf 会 wa,今天终于遇到了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 500 + 10;
int n, m;
int Graph[maxn][maxn];
int dis[maxn];
bool vis[maxn];

void Dijkstra(void);

int main()
{
    int System = 0;
    while (scanf("%d%d", &n, &m) != EOF && !(n ==0 && m == 0)) {
        ++System;
        printf("System #%d\n", System);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (i == j) {
                    Graph[i][j] = 0;
                } else {
                    Graph[i][j] = INF;
                }
            }
        }
        int a, b, l;
        for (int i = 0; i < m; ++i) {
            scanf("%d%d%d", &a, &b, &l);
            Graph[a][b] = Graph[b][a] = l;
        }
        Dijkstra();
        double Max1 = -INF;
        int pos;
        for (int i = 1; i <= n; ++i) {
            if (dis[i] > Max1) {
                Max1 = dis[i];
                pos = i;
            }
        }
        double Max2 = -INF;
        int pos1, pos2;
        for (int i = 1; i <= n; ++i) {
            for (int j = i+1; j <= n; ++j) {
                if (Graph[i][j] != INF) {
                    double t = (dis[j] + dis[i] + Graph[i][j]) / 2.0;
                    if (t > Max2) {
                        Max2 = t;
                        pos1 = i; pos2 = j;
                    }
                }
            }
        }
        if (Max2 > Max1) {
            printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n", Max2, pos1, pos2);
        } else {
            printf("The last domino falls after %.1f seconds, at key domino %d.\n", Max1, pos);
        }
        printf("\n");
    }
    return 0;
}

void Dijkstra(void)
{
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; ++i) {
        dis[i] = Graph[1][i];
    }
    for (int i = 0; i < n-1; ++i) {
        int Min = INF;
        int t;
        for (int j = 2; j <= n; ++j) {
            if (!vis[j] && dis[j] < Min) {
                Min = dis[j];
                t = j;
            }
        }
        if (Min == INF) {
            break;
        }
        vis[t] = true;
        for (int j = 2; j <= n; ++j) {
            if (!vis[j] && dis[j] > dis[t] + Graph[t][j]) {
                dis[j] = dis[t] + Graph[t][j];
            }
        }
    }
}

3、团队程序设计天梯赛-练习集-L2-001 紧急救援

解题思路:

dijkstra变形,第一个输出的是最短路的条数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const ull mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 500 + 10;
int N, M, S, D;
int num[maxn];
int Graph[maxn][maxn];
int dis[maxn];
bool vis[maxn];
int sum[maxn];
int pre[maxn];
int pathnum[maxn];

void Dijkstra(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d%d%d%d", &N, &M, &S, &D);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &num[i]);
    }
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            if (i == j) {
                Graph[i][j] = 0;
            } else {
                Graph[i][j] = INF;
            }
        }
    }
    int a, b, len;
    for (int i = 0; i < M; ++i) {
        scanf("%d%d%d", &a, &b, &len);
        Graph[a][b] = min(len, Graph[a][b]);
        Graph[b][a] = Graph[a][b];
    }
    Dijkstra();
    printf("%d %d\n", pathnum[D], sum[D]);
    stack<int> Stack;
    int t = D;
    while (pre[t] != t) {
        Stack.push(t);
        t = pre[t];
    }
    printf("%d", S);
    while (!Stack.empty()) {
        printf(" %d", Stack.top());
        Stack.pop();
    }
    printf("\n");
    return 0;
}

void Dijkstra(void)
{
    memset(vis, false, sizeof(vis));
    for (int i = 0; i < N; ++i) {
        dis[i] = INF;
    }
    dis[S] = 0;
    vis[S] = true;
    sum[S] = num[S];
    pathnum[S] = 1;
    for (int i = 0; i < N; ++i) {
        if (i != S && Graph[S][i] != INF) {
            dis[i] = Graph[S][i];
            pre[i] = S;
            sum[i] = num[S] + num[i];
            pathnum[i] = 1;
        }
    }
    for (int i = 0; i < N-1; ++i) {
        int Min = INF;
        int t;
        for (int j = 0; j < N; ++j) {
            if (!vis[j] && dis[j] < Min) {
                Min = dis[j];
                t = j;
            }
        }
        if (Min == INF) {
            break;
        }
        vis[t] = true;
        for (int j = 0; j < N; ++j) {
            if (!vis[j]) {
                int dis_t = dis[t] + Graph[t][j];
                if (dis_t < dis[j]) {
                    dis[j] = dis_t;
                    pre[j] = t;
                    pathnum[j] = pathnum[t];
                    sum[j] = sum[t] + num[j];
                } else if (dis_t == dis[j]) {
                    pathnum[j] += pathnum[t];
                    if (sum[j] < sum[t] + num[j]) {
                        sum[j] = sum[t] + num[j];
                        pre[j] = t;
                    }
                }
            }
        }
    }
}

4、HDU 2066 一个人的旅行

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 10;
int T, S, D;
int G[maxn][maxn];
int dis[maxn];
bool vis[maxn];
int Citys_num = 0;

void Dijkstra(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    while (scanf("%d%d%d", &T, &S, &D) != EOF) {
        int a, b, time;
        for (int i = 0; i < maxn; ++i) {
            for (int j = 0; j < maxn; ++j) {
                if (i == j) {
                    G[i][j] = 0;
                } else {
                    G[i][j] = INF;
                }
            }
        }
        Citys_num = 0;
        while (T--) {
            scanf("%d%d%d", &a, &b, &time);
            if (time < G[a][b]) {
                G[a][b] = G[b][a] = time;
                Citys_num = max(Citys_num, max(a, b));
            }
        }
        for (int i = 1; i <= Citys_num; ++i) {
            dis[i] = INF;
        }
        int Connect_City;
        while (S--) {
            scanf("%d", &Connect_City);
            dis[Connect_City] = 0;
        }
        Dijkstra();
        int Min = INF;
        int Target_City;
        while (D--) {
            scanf("%d", &Target_City);
            if (dis[Target_City] < Min) {
                Min = dis[Target_City];
            }
        }
        printf("%d\n", Min);
    }
    return 0;
}

void Dijkstra(void)
{
    memset(vis, false, sizeof(vis));
    for (int i = 0; i < Citys_num; ++i) {
        int Min = INF;
        int t;
        for (int j = 1; j <= Citys_num; ++j) {
            if (!vis[j] && dis[j] < Min) {
                Min = dis[j];
                t = j;
            }
        }
        if (Min == INF) {
            break;
        }
        vis[t] = true;
        for (int j = 1; j <= Citys_num; ++j) {
            if (!vis[j] && dis[j] > dis[t] + G[t][j]) {
                dis[j] = dis[t] + G[t][j];
            }
        }
    }
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3 + 10;
int T, S, D;
int G[maxn][maxn];
int dis[maxn];
int Citys_num = 0;

struct Node {
    int End, dis;
    Node(int a, int b) {
        End = a, dis = b;
    }
    bool operator < (const Node& a) const {
        if (dis == a.dis) {
            return a.End > End;
        }
        return a.dis < dis;
    }
};

priority_queue<Node> Q;

void Dijkstra(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    while (scanf("%d%d%d", &T, &S, &D) != EOF) {
        while (!Q.empty()) {
            Q.pop();
        }
        int a, b, time;
        for (int i = 0; i < maxn; ++i) {
            for (int j = 0; j < maxn; ++j) {
                if (i == j) {
                    G[i][j] = 0;
                } else {
                    G[i][j] = INF;
                }
            }
        }
        Citys_num = 0;
        while (T--) {
            scanf("%d%d%d", &a, &b, &time);
            if (time < G[a][b]) {
                G[a][b] = G[b][a] = time;
                Citys_num = max(Citys_num, max(a, b));
            }
        }
        for (int i = 1; i <= Citys_num; ++i) {
            dis[i] = INF;
        }
        int Connect_City;
        while (S--) {
            scanf("%d", &Connect_City);
            dis[Connect_City] = 0;
            Q.push(Node(Connect_City, 0));
        }
        Dijkstra();
        int Min = INF;
        int Target_City;
        while (D--) {
            scanf("%d", &Target_City);
            if (dis[Target_City] < Min) {
                Min = dis[Target_City];
            }
        }
        printf("%d\n", Min);
    }
    return 0;
}

void Dijkstra(void)
{
    while (!Q.empty()) {
        int End_t = Q.top().End, dis_t = Q.top().dis;
        Q.pop();
        for (int i = 1; i <= Citys_num; ++i) {
            if (dis[i] > dis_t + G[End_t][i]) {
                dis[i] = dis_t + G[End_t][i];
                Q.push(Node(i, dis[i]));
            }
        }
    }
}

5、POJ 2502 Subway

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
#include <bitset>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int, int> Pair;

const ull mod = 1e9 + 7;
const double INF = 1e30;
const int maxn = 300;

vector<Pair> coordinate;
double G[maxn][maxn];
double Time[maxn];
bool vis[maxn];
double dis_t;
int Size;
int station[maxn];
int Sta_Count = 0;

double dis(int x1, int y1, int x2, int y2);

int Push(int x, int y);
void Dijkstra(void);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    coordinate.clear();
    for (int i = 0; i < maxn; ++i) {
        for (int j = 0; j < maxn; ++j) {
            if (i == j) {
                G[i][j] = 0;
            } else {
                G[i][j] = INF;
            }
        }
    }
    int x, y;
    scanf("%d %d", &x, &y);
    coordinate.push_back(make_pair(x, y));
    scanf("%d %d", &x, &y);
    coordinate.push_back(make_pair(x, y));
    while (scanf("%d %d", &x, &y) != EOF) {
        Sta_Count = 0;
        station[Sta_Count++] = Push(x, y);
        while (scanf("%d %d", &x, &y) != EOF && !(x == -1 && y == -1)) {
            station[Sta_Count++] = Push(x, y);
        }
        for (int i = 0; i < Sta_Count-1; ++i) {
            dis_t = dis(coordinate[station[i]].first, coordinate[station[i]].second, coordinate[station[i+1]].first, coordinate[station[i+1]].second);
            G[station[i]][station[i+1]] = G[station[i+1]][station[i]] = dis_t * 3.0 / 2000.0;
        }
    }
    ++Size;
    for (int i = 0; i < Size-1; ++i) {
        for (int j = i+1; j < Size; ++j) {
            dis_t = dis(coordinate[i].first, coordinate[i].second, coordinate[j].first, coordinate[j].second);
            G[i][j] = G[j][i] = min(G[i][j], dis_t * 3.0 / 500.0);
        }
    }
    Dijkstra();
    printf("%d\n", (int)floor(Time[1] + 0.5));
    return 0;
}

double dis(int x1, int y1, int x2, int y2)
{
    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}

int Push(int x, int y)
{
    Size = coordinate.size();
    for (int i = 0; i < Size; ++i) {
        if (x == coordinate[i].first && y == coordinate[i].second) {
            return i;
        }
    }
    coordinate.push_back(make_pair(x, y));
    return Size;
}

void Dijkstra(void)
{
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= Size; ++i) {
        Time[i] = G[0][i];
    }
    for (int i = 0; i < Size-1; ++i) {
        double Min = INF;
        int t = -1;
        for (int j = 1; j < Size; ++j) {
            if (!vis[j] && Time[j] < Min) {
                Min = Time[j];
                t = j;
            }
        }
        if (t == -1) {
            break;
        }
        vis[t] = true;
        for (int j = 1; j < Size; ++j) {
            if (!vis[j] && Time[j] > Time[t] + G[t][j]) {
                Time[j] = Time[t] + G[t][j];
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值