此题是求特定两点之间路径乘积的最大值,可以将原路径值取以小于1的数为底的对数值,然后套用Dijkstra算法即可。
Dijkstra算法与Prim算法很接近,但要明确Dijkstra算法求的是某个特定顶点到其他所有顶点的最短路径,此特定顶点属于特殊点,须最先纳入已找到顶点的集合中;而Prim算法则只是求最小生成树,顶点之间无区别,故第一个纳入已找到顶点集合的可以是任意点。因此,在每纳入一个顶点后,对顶点最短路径值进行修正时,Dijkstra算法考虑的是以纳入的顶点为中间结点时,从特定顶点到该中间结点及该中间结点到某顶点的距离之和是否小于已有的特定顶点到某顶点的距离值;而Prim算法考虑的是某顶点到刚纳入的结点的距离值是否小于已有的到某顶点的距离值。
code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//poj2472
#define N 101
#define INF 10
int main()
{
int i, j, n, m, a, b, p, minindex, preindex;
char included[N], prenode[N];
double prob[N][N], mindist[N], result;
scanf("%d", &n);
while (n != 0)
{
for (i=0; i<n; i++)
for (j=0; j<n; j++)
prob[i][j] = INF;
scanf("%d", &m);
for (i=0; i<m; i++)
{
scanf("%d%d%d", &a, &b, &p);
prob[a - 1][b - 1] = prob[b - 1][a - 1] = -log10(p / 100.0);
}
included[0] = 1;
preindex = 0;
minindex = 1;
for (i=1; i<n; i++)
{
included[i] = 0;
prenode[i] = preindex;
mindist[i] = prob[preindex][i];
if (mindist[i] < mindist[minindex])
{
minindex = i;
}
}
while (1)
{
included[minindex] = 1;
if (minindex == n - 1)
break;
preindex = minindex;
minindex = n - 1;
for (i=1; i<n; i++)
{
if (!included[i] && mindist[i] > mindist[preindex] + prob[preindex][i])
{
mindist[i] = mindist[preindex] + prob[preindex][i];
prenode[i] = preindex;
}
if (!included[i] && mindist[minindex] > mindist[i])
minindex = i;
}
}
result = pow(0.1, mindist[n - 1]);
printf("%.6lf percent\n", result * 100);
scanf("%d", &n);
}
return 0;
}