UVa10354 - Avoiding Your Boss(Dijkstra的巧妙用法 ,针对有多个最短路径)

Imagine that like me you are alsoan idle but reasonably good programmer. On one fine morning you wake up fromsleep and discover that your bed is such a lovely place and you must not leaveit for the miserable place called office. So you just pick up your mobilephone, call your boss with a gloomy voice and tell him that you are quite sick.Your boss is a very strict but sympathetic person and so he grants you leavevia phone. As the day grows old you discover that you must go out for shopping.But you are afraid that your boss might see you. So you need to know if thereis any safe option to reach the market. You know that your boss stays only intwo places, his residence and the office. While going from one place to anotherhe uses a path that does not cost more than any other path. So you must avoidsuch paths and even places that your boss may reach. Your boss must not see yououtside your home. You can assume that the cost of reaching another location inthe same place is zero and you must go outside your home to reach market andyour boss must come outside to reach home (from office) or office (from home).As your job is at stake so you cannot take any chances.

 

Input

The input file contains severalsets of input. Each set of input starts with six integers P, R, BH, OF, YH andM. Here

 

               P = Total number of places. (0<P<=100)

               R = Total number of connecting roads.(0<=R<=4950)

               BH = The Place where your boss lives. (0<BH<=P)

               OF = The place where your office is situated. (0<OF<=P)

               YH = The place where your home is situated. (0<YH<=P)

               M = The place where the market is situated. (0<M<=P)

               

Next R lines contain descriptionof the city. Each line contains three integers p1, p2 and d. These threeintegers denote that place p1 and place p2 is connected by a road whose cost isd. Here (0<p1, p2<=P) and d is a positive integer less than 101. Streetsare all bi-directional. You can assume that twodifferent places are connected by only one road.Input isterminated by end of file.

 

Output

For each set of input produce oneline of output. This line contains the cost of going from your home to themarket. If it is not possible for you to go to the market avoiding your bossprint the line ‘MISSIONIMPOSSIBLE.’ (Without the quotes).

 

Sample Input
3 2 2 3 1 3

1 24

2 34

3 22 3 3 3

1 24

2 34

4 32 3 1 4

1 24

2 34

1 410


Sample Output
MISSION IMPOSSIBLE.

MISSION IMPOSSIBLE.

10

题意:给出两个起点,终点,一个对应是老板的,一个是对应你的,走的都是最短路径,但是你走的路径不能与老板的有重合
思路:先求出老板的最短路径,注意,可能有多种路径(即这几种路径的权值都是相等,并且是最短路径),先以起点做Dijkstra,再以终点做Dijkstra,然后遍历,如果路径权值相等,就将路径删除。然后再计算你的从起点到终点的最短路径

#include <cstdio>

using namespace std;

const int INF = 0x1fffffff;
const int MAXN = 128;

int adj[MAXN][MAXN];
bool ban[MAXN], vis[MAXN];
int p, r, bh, of, yh, m;
int d[MAXN], e[MAXN];

bool input()
{
    if (scanf("%d%d%d%d%d%d", &p, &r, &bh, &of, &yh, &m) != 6) return false;

    for (int i = 1; i <= p; i++) {
        for (int j = 1; j <= p; j++) adj[i][j] = INF;
    }

    for (int i = 0; i < r; i++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        if (adj[a][b] > c) adj[a][b] = adj[b][a] = c;
    }

    return true;
}

void dijkstra(int a[], int s)
{
    for (int i = 1; i <= p; i++) {
        vis[i] = ban[i];
        a[i] = INF;
    }

    a[s] = (ban[s] ? INF : 0);

    int i, j;
    for (;;) {
        for (i = 1; i <= p && vis[i]; i++);
        for (j = i + 1; j <= p; j++) {
            if (!vis[j] && a[j] < a[i]) i = j;
        }

        if (i > p || a[i] >= INF) break;
        vis[i] = true;
        for (j = 1; j <= p; j++) {
            if (a[i] + adj[i][j] < a[j]) a[j] = a[i] + adj[i][j];
        }
    }

    for (i = 1; i <= p; i++) {
        if (ban[i]) a[i] = INF;
    }
}

void solve()
{
    for (int i = 1; i <= p; i++) ban[i] = false;
    dijkstra(d, bh);
    dijkstra(e, of);

    for (int i = 1; i <= p; i++) {
        for (int j = 1; j <= p; j++) {
            if (adj[i][j] != INF && d[i] + adj[i][j] + e[j] == d[of]) {
                adj[i][j] = adj[j][i] = INF;
            }
        }
    }

    for (int i = 1; i <= p; i++) {
        ban[i] = (d[i] + e[i] == d[of]);
    }

    dijkstra(d, yh);
    if (d[m] >= INF) printf("MISSION IMPOSSIBLE.\n");
    else printf("%d\n", d[m]);

}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("d:\\OJ\\uva_in.txt", "r", stdin);
    #endif // ONLINE_JUDGE

    while (input()) {
        solve();
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值