pku1734 Floyd_Warshal算法应用 解题报告

本文介绍了一种使用Floyd_Warshall算法解决寻找最优旅游路线的问题,旨在找出路径最短且经过景点最多的回路。通过具体代码实现,展示了如何更新路径矩阵并记录最佳路线。

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

一、题目:Sightseeing trip

二、题意:给出N个旅游景点与M跳旅游路线,选择一条总路径最短且旅游景点又最多,而且是从头到尾是一条回路。

三、解决办法:

      此题其实是经典的Floyd_Warshal算法。

四、源代码:

#include "stdio.h"

#include "string.h"

 

const int n = 101;

const int MAXINT = 123456789;

int N, M;                

int d[n][n];                      //ij的最短路径

int Memory[n][n];         //记录i可以到那些旅游景点

int Initial[n][n];              //记录最初的路径

int result[n];                   //记录最佳回路

int num;                          //记录最佳回路旅游景点的个数

int best;

 

void floyd()

{

       int i, j, k;

       int sum;     //记录当前一个回路的权值

       int p;

 

       //Floyd_Warshell算法:

    for (k = 0; k < N; ++k)

       {

        for (i = 0; i < k; ++i)

              {

            for (j = 0; j < k; ++j)

                     {

                            //判断ij是否可行

                            if (Initial[i][k] && Initial[k][j] && j != i)

                            {

                                   //记录k-i-j-k一个回路的权值

                                   if ((sum = d[i][j] + Initial[k][i] + Initial[j][k]) < best)

                                   {

                                          best = sum;

                                          num = 1;

                                          result[0] = k;      //记录第一个景点k

                                          p = i;            

                                          while (p != -1)     //一直都在记录回路的景点数目,直到没有为止

                                          {

                                                 result[num++] = p;  

                                                 p = Memory[p][j];

                                          }

                                   }

                            }

                     }

        }

              //k为中心的话,记录ij较小值(其中可能经过>2的旅游景点),

              //同时改变Memory记录的内容

              for (i = 0; i < N; ++i)

              {

                     for (j = 0; j < N; ++j)

                     {

                            if (d[i][j] > d[i][k] + d[k][j])

                            {

                    d[i][j] = d[i][k] + d[k][j];

                    Memory[i][j] = Memory[i][k];

                }

            }

              }

       }

}

 

int main()

{

       freopen("1.txt", "r", stdin);

       int i, j, u, v, w;

 

    memset(Memory, -1, sizeof(Memory));

 

    scanf("%d %d", &N, &M);

       //初始化

    for (i = 0; i < N; ++i)

       {

        for (j = i + 1; j < N; ++j)

              {

                     d[i][j] = d[j][i] = MAXINT;

              }

        d[i][i] = 0;

    }

    for (i = 0; i < M; ++i)

       {

        scanf("%d %d %d", &u, &v, &w);

        u--;

              v--;

        if (w < d[u][v])    

              {

                     Initial[u][v] = Initial[v][u] = d[u][v] = d[v][u] = w;

              }

        Memory[u][v] = v;     //记录点(u, v)可以到的下一点为v

              Memory[v][u] = u;     //记录点(v, u)可以到的下一点为u

    }

    best = MAXINT;           

    floyd();

 

       //输出

    if (best == MAXINT)

       {

              printf("No solution./n");

       }

    else

       {

              for (i = 0; i < num; ++i)

              {

            printf("%d", result[i] + 1);

                     if (i != num - 1)

                     {

                            putchar(' ');

                     }

            else

                     {

                            putchar('/n');

                     }

        }

    }

 

    return 0;

}

五、memory:316k time:32ms

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值