1.题目编号:1016
2.简单题意:XX星球有很多城市,每个城市之间有一条或多条飞行通道,但是并不是所有的路都是很安全的,每一条路有一个安全系数s,s是在 0 和 1 间的实数(包括0,1),一条从u 到 v 的通道P 的安全度为Safe(P) = s(e1)*s(e2)…*s(ek) e1,e2,ek是P 上的边,现在8600 想出去旅游,面对这这么多的路,他想找一条最安全的路。但是8600 的数学不好,想请你帮忙
3.解题思路形成过程:找一条最安全的路则需要安全度最大,因为ek是P上的边,而且s是在0~1之间的数,相乘的越少则安全度越大,所以还是一个最短路径的问题,可以用dijstral算法求得。
4.感悟:乍一看,求安全度最大我还以为是求最长路径呢,仔细分析之后其实就是最短路径的变形。用cin输入会超时,还是C语言的输入输出好用=.=
5.AC的代码:
#include <iostream>
#include <stdio.h>
#include <string>
#define M 1001
using namespace std;
int n,m;
double S[M][M],dis[M];
void Dijkstra(int x,int y)
{
bool v[M]={0};
int i,j;
for(i=1;i<=n;i++) dis[i]=(i==x?1:0);
for(i=1;i<=n;i++)
{
int k;
double Min=0;
for(j=1;j<=n;j++) if(!v[j] && dis[j]>Min) Min=dis[k=j];
v[k]=1;
for(j=1;j<=n;j++) dis[j]=max(dis[j],dis[k]*S[k][j]);
}
if(dis[y]) printf("%.3lf\n",dis[y]);
else cout<<"What a pity!"<<endl;
}
int main()
{
int i,j;
int a,b,c;
while(cin>>n && n)
{
memset(S,0,sizeof(S));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%lf",&map[i][j]);
}
cin>>m;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
Dijkstra(a,b);
}
}
return 0;
}
原题:
3 1 0.5 0.5 0.5 1 0.4 0.5 0.4 1 3 1 2 2 3 1 3
0.500 0.400 0.500