码迷,mamicode.com
首页 > Web开发 > 详细

POJ 2472 106 miles to Chicago(Dijstra变形——史上最坑的最长路问题)

时间:2017-10-09 21:06:42      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:ons   log   intersect   lan   最大   href   desc   应该   office   

题目链接 :
http://poj.org/problem?id=2472

Description

In the movie "Blues Brothers", the orphanage where Elwood and Jack were raised may be sold to the Board of Education if they do not pay 5000 dollars in taxes at the Cook Country Assessor‘s Office in Chicago. After playing a gig in the Palace Hotel ballroom to earn these 5000 dollars, they have to find a way to Chicago. However, this is not so easy as it sounds, since they are chased by the Police, a country band and a group of Nazis. Moreover, it is 106 miles to Chicago, it is dark and they are wearing sunglasses.
As they are on a mission from God, you should help them find the safest way to Chicago. In this problem, the safest way is considered to be the route which maximises the probability that they are not caught.

Input

The input contains several test cases.
Each test case starts with two integers n and m (2 <= n <= 100 , 1 <= m <= n*(n-1)/2). n is the number of intersections, m is the number of streets to be considered.
The next m lines contain the description of the streets. Each street is described by a line containing 3 integers a, b and p (1 <= a, b <= n , a != b, 1 <= p <= 100): a and b are the two end points of the street and p is the probability in percent that the Blues Brothers will manage to use this street without being caught. Each street can be used in both directions. You may assume that there is at most one street between two end points.
The last test case is followed by a zero.

Output

For each test case, calculate the probability of the safest path from intersection 1 (the Palace Hotel) to intersection n (the Honorable Richard J. Daley Plaza in Chicago). You can assume that there is at least one path between intersection 1 and n.
Print the probability as a percentage with exactly 6 digits after the decimal point. The percentage value is considered correct if it differs by at most 10-6 from the judge output. Adhere to the format shown below and print one line for each test case.

Sample Input

5 7
5 2 100
3 5 80
2 3 70
2 1 50
3 4 90
4 1 85
3 1 70
0

Sample Output

61.200000 percent
题意描述:
  输入顶点数和边的条数以及从无向边,不同的是表示从a到b不被抓住的概率是p
计算并输出从1到n他们不被抓住的最大概率
解题思路:
  首先单源最长路问题,Dijstra再合适不过了,但是套模板的话,多半是会错的,因为涉及一点数学概率知识。但是使用求最短路的Flyod算法敲模板也能过。
先说一下Dijstra算法涉及的一点点数学概率知识。
  一般来说我们使用Dijstra算法求最短路问题,dis数组存储的是1号顶点到其他各个顶点的直接距离,这个是固有属性,不管之前的点是哪个,只要
要使用该点,那么该点到各个顶点的距离不会因为之前使用的顶点而改变,但是,但是本题求的是不被抓住的最大概率,它由多个事件达成,换句话说,使用事件发生的概率乘法计数原理时,
之前的时间发生会影响后续事件发生的概率。
  所以我们初始化dis数组时,应该除了1号顶点置为1以外(因为走到1号顶点的概率是百分之百),其他先置为0,因为只有走到某个顶点了,再将该顶点到其他各顶点的距离进行一个更新。
剩下的就是使用Dijstra算法变形求解最长路啦。
上代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int inf=99999999;

double map[110][110];
int main()
{
    int n,m,i,j,u,v;
    int a,b;
    int book[110];
    double c,p[110];
    while(scanf("%d",&n), n != 0)
    {
        scanf("%d",&m);
        memset(map,0,sizeof(map));
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%lf",&a,&b,&c);
            map[a][b]=map[b][a]=c/100;
        }
        memset(book,0,sizeof(book));
        book[1]=1;
        memset(p,0,sizeof(p));
        p[1]=1;
        for(i=1;i<=n-1;i++)
        {
            u=1;
            double maxp=0;
            for(j=1;j<=n;j++)
            {
                if(!book[j] && p[j] > maxp)
                {
                    maxp=p[j];
                    u=j;
                }
            }
            book[u]=1;
            for(v=1;v<=n;v++)
            {
                if(p[v] < p[u]*map[u][v])
                    p[v]=p[u]*map[u][v];
            }
        }
        printf("%.6lf percent\n",p[n]*100.0);
    }
    return 0;
}

再说一下Flyod算法,使用这个算法直接跑的话,因为是最先加入一个点进行松弛,事情也是连续的,也是遵循乘法原理的。

#include<cstdio.h>
#include<string.h>
#include<math.h>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int inf=99999999;

double map[110][110];
int main()
{
    int n,m,i,j,k;
    int a,b;
    double c;
    while(scanf("%d",&n), n != 0)
    {
        scanf("%d",&m);
        memset(map,0,sizeof(map));
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%lf",&a,&b,&c);
            map[a][b]=map[b][a]=c/100;
        }
        for(k=1;k<=n;k++)
            for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)
                    if(map[i][j] < map[i][k] * map[k][j])
                        map[i][j] = map[i][k] * map[k][j];
        printf("%.6lf percent\n",map[1][n]*100);
    }
    return 0;
}

 



POJ 2472 106 miles to Chicago(Dijstra变形——史上最坑的最长路问题)

标签:ons   log   intersect   lan   最大   href   desc   应该   office   

原文地址:http://www.cnblogs.com/wenzhixin/p/7642627.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!