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; }