Problem Description
找到v1 - v1 的最长路径,
已经给出 一个n*n的矩阵表示两个城市之间的安全系数 s [0,1].
给出最长路的计算公式,一条从u 到 v 的通道P 的安全度为Safe(P) = s1*s2…*sk 1, 2, k是P 上的边
Input
输入包括多个测试实例,每个实例包括:
第一行:n。n表示城市的个数n<=1000;
接着是一个n*n的矩阵表示两个城市之间的安全系数,(0可以理解为那两个城市之间没有直接的通道)
接着是Q个8600要旅游的路线,每行有两个数字,表示8600所在的城市和要去的城市
第一行:n。n表示城市的个数n<=1000;
接着是一个n*n的矩阵表示两个城市之间的安全系数,(0可以理解为那两个城市之间没有直接的通道)
接着是Q个8600要旅游的路线,每行有两个数字,表示8600所在的城市和要去的城市
Output
如果86无法达到他的目的地,输出"What a pity!",
其他的输出这两个城市之间的最安全道路的安全系数,保留三位小数。
其他的输出这两个城市之间的最安全道路的安全系数,保留三位小数。
Sample Input
3 1 0.5 0.5 0.5 1 0.4 0.5 0.4 1 3 1 2 2 3 1 3
Sample Output
0.500 0.400 0.500
分析:
伪最长路径,其实还是最短路算法,
因为规定两个点之间的权值是相乘并且权值是 [0, 1] 的!!!!这一点很重要,
因为,这样的话,就能保证用dijkstra 的话, 每次找到离源点最远的那个点的最长路径已经确定!!不会经过第三个点更长!!
记得把 G 初始化~!
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<double, int> P; // first 是距离, second 是顶点编号
struct Edge
{
int v;
double w;
};
vector<Edge> G[1003];
double dis[1003];
Edge t;
void dijkstra(int s, int e)
{
priority_queue<P, vector<P>, less<P>> q;
// 先把源点放入队列,从源点开始
q.push(P(1, s));
dis[s] = 1;
while (!q.empty())
{
// a 是队列中离源点最远的点
P T = q.top();
q.pop();
int a = T.second;
// 枚举与a 相连的点
if (dis[a] != T.first)
continue;
for (int i = 0; i < G[a].size(); i++)
{
Edge v1 = G[a][i];
// printf("%.3lf %.3lf ",dis[v1.v],dis[a]*v1.w);
if (dis[v1.v] < dis[a] * v1.w)
{
dis[v1.v] = dis[a] * v1.w;
q.push(P(dis[v1.v], v1.v));
//printf("%lf ",dis[v1.v]);
}
}
}
if (dis[e] == 0)
printf("What a pity!\n");
else
printf("%.3lf\n", dis[e]);
return;
}
int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
for (int i = 1; i <= n; i++)
G[i].clear();
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
t.v = j;
scanf("%lf", &t.w);
G[i].push_back(t);
}
}
int n1;
scanf("%d", &n1);
for (int i = 0; i < n1; i++)
{
for (int i = 1; i <= n; i++)
dis[i] = -1;
int a, b;
scanf("%d %d", &a, &b);
dijkstra(a, b);
}
}
return 0;
}