题目:
大家都知道,在天朝无论使用哪种交通工具出行都是很不安全的,但是当你必须出远门的时候也就不得不冒着生命危险和自己的人生进行一场博弈了。
我们可怜的胖哥现在就遇到了这种囧状,为了参加ACM/ICPC火星赛区的比赛,他必须从天朝所在的星球乘坐某种特殊的交通工具到达那里(Amazing……)。
假设胖哥所在的宇宙有n个星球,胖哥所在的星球编号为1,火星编号为n。
我们姑且认为这种交通工具是一种车,共有m趟车次,每趟车次都从一个星球开往另一个星球,并且每趟车次都有一个失事率,表示了胖哥做这趟车次出事故的概率。
大家都知道,胖哥还小,还没有感受够这个世界,他想尽可能安全的到达火星,于是他请求你给予帮助,希望能够求出一条路线,使得他到达火星的出事概率越小越好。
当然如果从天朝到火星还没通车,那么胖哥自然连冒生命危险的机会也没有,他就可以安心的在家里打游戏了。
题中数据保证如果从A点可以到达B点,那么从B点绝对不可能到达A点
Input
输入一个数字t,表示共有t组测试样例。
对于每组测试样例,首先输入两个数字n和m,表示共有n个星球,有m个车次
接下来跟着是m行,每行先是两个整数x和y,表示有车次从编号为x的星球通往编号为y的星球
然后是一个实数s,表示这辆车的失事率,注意是失事率,也就是胖哥挂掉的概率
Output
如果胖哥不能到达火星,输出“Stayat home!”
否则输出一个实数,表示胖哥到达火星的最小失事率,结果保留五位小数
Sample Iutput
6
2 1
1 2 0.10000
2 2
1 2 0.10000
1 2 0.20000
3 2
1 2 0.10000
2 3 0.10000
3 2
1 2 0.10000
1 2 0.20000
2 1
1 2 0.00000
2 1
1 2 1.00000
Sample Output
Case 1: 0.10000
Case 2: 0.10000
Case 3: 0.19000
Case 4: Stay at home!
Case 5: 0.00000
Case 6: 1.00000
数据范围
t<=100,2<=n<=100,1<=m<=1000,1<=x,y<=n,0<=s<=1
Hint
请使用doudle,输入用%lf,输出用%f
思路:floyd求最大值
分析:
1 题目要求的是最小的失事率。我们知道只要有一辆车失事那么就算失事,所以我们应该要先算安全的概率,然后1-概率。这样才是失事的概率
2 题目要求的最小的失事率,那么就要有最大的安全率,所以我们利用floyd求最大的安全率,然后判断即可。
3 floyd求最大值的时候,应该全部初始化为-1
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 110 int t , n , m; double dis[MAXN][MAXN]; /*初始化*/ void init(){ for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= n ; j++) dis[i][j] = -1; } void floyd(){ for(int k = 1 ; k <= n ; k++){ for(int i = 1 ; i <= n ; i++){ for(int j = 1 ; j <= n ; j++) if(dis[i][k] != -1 && dis[k][j] != -1)/*加上这一句判断是否有边*/ dis[i][j] = max(dis[i][j] , dis[i][k]*dis[k][j]); } } } int main(){ scanf("%d", &t); int Case = 1; int a , b; double s; while(t--){ scanf("%d%d" , &n , &m); init(); for(int i = 0 ; i < m ; i++){ scanf("%d%d%lf" , &a , &b , &s); s = 1-s;/*求出安全的概率*/ if(dis[a][b] < s) dis[a][b] = s; } floyd(); if(dis[1][n] == -1) printf("Case %d: Stay at home!\n" , Case++); else printf("Case %d: %0.5f\n" , Case++ , 1-dis[1][n]); } return 0; }