poj2472解题报告——化用Dijkstra算法

这篇博客探讨了如何使用Dijkstra算法解决特定两点间路径乘积最大值的问题。通过将路径值转换为对数值,算法可以适应求解这一优化问题。文章对比了Dijkstra算法与Prim算法的区别,并提供了相关代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        此题是求特定两点之间路径乘积的最大值,可以将原路径值取以小于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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值