首页 > 其他分享 >7-8 旅行售货员

7-8 旅行售货员

时间:2023-12-23 22:12:44浏览次数:24  
标签:旅行 fee int siz ++ vis ans 售货员

7-8 旅行售货员

某售货员要到若干城市去推销商品,已知各城市之间的路程(或旅费)。他要选定一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总的路程(或总旅费)最小。

输入格式:

第一行为城市数n

下面n行n列给出一个完全有向图,如 i 行 j 列表示第 i 个城市到第 j 个城市的距离。

输出格式:

一个数字,表示最短路程长度。

输入样例:

3
0 2 1
1 0 2
2 1 0

输出样例:

3

简化版代码

解释:下面这个代码是没有进行剪枝的,也就是说没有优化,但是可以过pta,所以我也给出

#include <iostream>

const int N = 20;

bool vis[N];
int n, mp[N][N], ans = 0x3f3f3f3f;

void dfs(int u, int siz, int fee)
{
    for (int i = 0; i < n; ++i) {
        if (i == u || vis[i]) continue;
        vis[i] = true;
        dfs(i, siz + 1, fee + mp[u][i]);
        vis[i] = false;
    }
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            scanf("%d", &mp[i][j]);

    dfs(0, 0, 0);

    printf("%d", ans);
  
    return 0;
}

解释:这个代码是在上面这个代码的基础上加上了剪枝的代码,也就是优化了一下,如果只是为了过pta,用上面这份代码就够了

这个是优化的部分代码

    if (siz == n && ans > fee) {
        ans = fee;
    }
    if (fee >= ans || siz >= n) return ;
    if (siz < n - 1 && vis[0]) return ;

完整代码:

#include <iostream>

const int N = 20;

bool vis[N];
int n, mp[N][N], ans = 0x3f3f3f3f;

void dfs(int u, int siz, int fee)
{
    if (siz == n && ans > fee) {
        ans = fee;
    }
    if (fee >= ans || siz >= n) return ;
    if (siz < n - 1 && vis[0]) return ;

    for (int i = 0; i < n; ++i) {
        if (i == u || vis[i]) continue;
        vis[i] = true;
        dfs(i, siz + 1, fee + mp[u][i]);
        vis[i] = false;
    }
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            scanf("%d", &mp[i][j]);

    dfs(0, 0, 0);

    printf("%d", ans);
  
    return 0;
}

注释版代码

#include <iostream>

const int N = 20;

bool vis[N];
int n, mp[N][N], ans = 0x3f3f3f3f;

// 深度优先搜索函数
void dfs(int u, int siz, int fee)
{
    // 如果已经找到了一种方案且费用更低,更新答案
    if (siz == n && ans > fee) {
        ans = fee;
    }

    // 如果当前费用已经超过当前答案或者已经选择了足够的点,结束递归
    if (fee >= ans || siz >= n) return;

    // 如果还需要选择一个点但是第一个点已经被选中,结束递归
    if (siz < n - 1 && vis[0]) return;

    // 遍历所有未被选择的点
    for (int i = 0; i < n; ++i) {
        if (i == u || vis[i]) continue;

        // 选择一个点并递归
        vis[i] = true;
        dfs(i, siz + 1, fee + mp[u][i]);
      
        // 恢复状态,回溯
        vis[i] = false;
    }
}

int main()
{
    // 输入点的数量
    scanf("%d", &n);

    // 输入图的邻接矩阵
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            scanf("%d", &mp[i][j]);

    // 从第一个点开始进行深度优先搜索
    dfs(0, 0, 0);

    // 输出最小费用
    printf("%d", ans);

    return 0;
}

java版代码

import java.util.Scanner;

public class Main {
    static final int N = 20;
    static boolean[] vis = new boolean[N];
    static int[][] mp = new int[N][N];
    static int n, ans = Integer.MAX_VALUE;

    // 深度优先搜索函数
    static void dfs(int u, int siz, int fee) {
        // 如果已经找到了一种方案且费用更低,更新答案
        if (siz == n && ans > fee) {
            ans = fee;
        }

        // 如果当前费用已经超过当前答案或者已经选择了足够的点,结束递归
        if (fee >= ans || siz >= n) return;

        // 如果还需要选择一个点但是第一个点已经被选中,结束递归
        if (siz < n - 1 && vis[0]) return;

        // 遍历所有未被选择的点
        for (int i = 0; i < n; ++i) {
            if (i == u || vis[i]) continue;

            // 选择一个点并递归
            vis[i] = true;
            dfs(i, siz + 1, fee + mp[u][i]);

            // 恢复状态,回溯
            vis[i] = false;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 输入点的数量
        n = scanner.nextInt();

        // 输入图的邻接矩阵
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                mp[i][j] = scanner.nextInt();
            }
        }

        // 从第一个点开始进行深度优先搜索
        dfs(0, 0, 0);

        // 输出最小费用
        System.out.println(ans);
    }
}

标签:旅行,fee,int,siz,++,vis,ans,售货员
From: https://www.cnblogs.com/aslwr/p/78-travel-salesperson-z1kxmjj.html

相关文章

  • 记识读《旅行用心集》自序
    经请教Lerearath老师后,修改的正解:夫(それ)人々家(か)業(ぎやう)の[能]暇(いとま)に[爾]伊勢(いせ)参(さん)道(だう)に[爾]旅(たび)立(たち)するとて其(その)用意(ようい)をなし道(み[三]ち)連(つれ)と[等]約(やく)束(そく)しいつ何日(いつか)は[盤]吉日と定(さだめ)爰(ここ)彼(かしこ)より[里]餞別(せんべつ)物(もの)抔......
  • vim编辑器命令模式——撤销与时间旅行
    原创:厦门微思网络Vi介绍Vi编辑器是所有Unix及Linux系统下标准的编辑器,类似于windows系统下的notepad(记事本)编辑器,由于在Unix及Linux系统的任何版本,Vi编辑器是完全相同的,因此可以在其他任何介绍vi的地方都能进一步了解它,Vi也是Linux中最基本的文本编辑器,学会它后......
  • 初中英语优秀范文100篇-016An unforgettable Trip-一次难忘的旅行
    PDF格式公众号回复关键字:SHCZFW016记忆树1Lastyear,Iwenttomyfavoritecity,Beijing.翻译去年,我去了我最喜欢的城市,北京简化记忆城市句子结构这个句子可以分析为一个复合句,由主句和从句构成。主句是“Iwenttomyfavoritecity,Beijing”,主语是“I”......
  • P1081 [NOIP2012 提高组] 开车旅行
    题目有点长,一步一步来。预处理出每座城市两人分别会选择的下一座城市用set即可实现。倍增优化DP令\(f_{i,j}\)表示从城市\(j\)出发,行驶\(2^i\)天会到达的城市。令\(ga_{i,j}\)表示从城市\(j\)出发,行驶\(2^i\)天,小A行驶的路程。\(gb_{i,j}\)同理。答案枚......
  • Car 的旅行路线
    [NOIP2001提高组]Car的旅行路线题目描述又到暑假了,住在城市A的Car想和朋友一起去城市旅游。她知道每个城市都有个飞机场,分别位于一个矩形的个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第个城市中高速铁路了的单位里程价格为,任意两个不同城市的机场之间均......
  • Solution - 公路旅行
    Link。又名:《不会T1记》。原来用到了神秘的倍增!但是我写了一个申必二分,最坏\(O(qn\logn)\),甚至不如暴力,我是......
  • 公告 & Solution - 公路旅行
    以后应该会用Obsidian搭个博客,博客园可能会被弃用了。为了有点价值放个不知道什么东西上来。Link。不会T1!原来用到了神秘的倍增!但是我写了一个申必二分,最坏\(O(qn\logn)\),甚至不如暴力,我是......
  • Xposed框架简单Hook实例:窥视“时间旅行”功能
    在我们的生活中,有时候我们希望能够改变一些事情,就像电影中的主人公可以通过时间旅行改变自己的命运一样。在Android系统中,Xposed框架就提供了一种类似的机会,让我们可以通过Hook技术改变应用程序的行为。本文将通过一个简单的例子来演示Xposed框架的基本使用,让我们一起来窥视一下“......
  • [NOIP2012 提高组] 开车旅行
    题目描述小AA和小BB决定利用假期外出旅行,他们将想去的城市从11到nn编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市ii的海拔高度为hihi​,城市ii和城市jj之间的距离di,jdi,j​恰好是这两个城市海拔高度之差的绝对值,即di,j=∣h......
  • APM建设踩了哪些坑?去哪儿旅行分布式链路追踪系统实践
    一分钟精华速览分布式链路追踪系统在企业的APM体系中扮演着重要的角色。本文分享了去哪儿旅行构建分布式链路追踪系统的实践经验。从APM整体架构设计入手,讲述了日志收集、Kafka传输和Flink任务处理等环节的性能优化实践和踩坑经验。同时,作者结合丰富的分布式系统架构经验,探讨了AP......