题目描述 Description

某乡有n个村庄(1<n<=15),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。

输入描述 Input Description

村庄数n和各村之间的路程(均是整数)

输出描述 Output Description

最短的路程

样例输入 Sample Input

3

0 2 1

1 0 2

2 1 0

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

本题可用最短路思想、搜索来解决,但是可能无法通过一组极限数据(且效率较低)。建议按树状DP考虑!

/*
不会什么树形DP,我做的是spfa(其实floyed就可以)+深搜+剪枝
首先将边反向,spfa处理所有点到1的距离,以备剪枝使用
然后深搜得到答案
剪枝:利用spfa得到的距离,当当前的dis+(n-t)*minn+f[x]>ans时,剪枝
(minn是矩阵中的最短距离,n-t是还有几步可以遍历完所有的村庄)
*/
#include<cstring>
#include<cstdio>
#include<iostream>
#include<queue>
#define M 20
#define INF 3000000
using namespace std;
int map[M][M],f[M],n,ans=INF,min1=INF;
int a2[M][M];
bool vis[M];
queue<int> q;
int read()
{
char c=getchar();int num=,flag=;
while(c<''||c>''){if(c=='-')flag=-;c=getchar();}
while(c>=''&&c<=''){num=num*+c-'';c=getchar();}
return num*flag;
}
void dfs(int x,int t,int dis)
{
if(dis>ans)return;
if(dis+(n-t)*min1+f[x]>ans)return;
if(t==n)
{
ans=min(ans,dis+map[x][]);
return;
}
for(int i=;i<=n;i++)
if(!vis[i])
{
vis[i]=true;
dfs(i,t+,dis+map[x][i]);
vis[i]=false;
}
}
void spfa()
{
q.push();
vis[]=;
f[]=;
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=;
for(int i=;i<=n;i++)
if(a2[x][i]&&f[x]+a2[x][i]<f[i])
{
f[i]=f[x]+a2[x][i];
if(!vis[i])
{
vis[i]=;
q.push(i);
}
}
}
}
int main()
{
memset(f,0x3f3f3f3f,sizeof(f));
n=read();
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
map[i][j]=read();
a2[j][i]=map[i][j];
min1=min(min1,map[i][j]);
}
spfa();
memset(vis,,sizeof(vis));
vis[]=;
dfs(,,);
printf("%d",ans);
return ;
}

售货员的难题(codevs 2596)的更多相关文章

  1. codevs 2596 售货员的难题

    2596 售货员的难题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某乡有n个村庄(1<n<=15),有一个售货 ...

  2. codevs2596 售货员的难题(状压dp)

    2596 售货员的难题  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 钻石 Diamond     题目描述 Description 某乡有n个村庄(1<n<=15 ...

  3. [swustoj 411] 售货员的难题

    售货员的难题(0411) Time limit(ms): 5000 Memory limit(kb): 65535 Submission: 1744 Accepted: 200 Description ...

  4. P1171 售货员的难题

    P1171 售货员的难题 题目描述 某乡有nn个村庄(1<n \le 201<n≤20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)s(0< ...

  5. 洛谷P1171 售货员的难题

    P1171 售货员的难题 题目背景 数据有更改 题目描述 某乡有n个村庄(1<n<20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且 ...

  6. 洛谷 P1171 售货员的难题

    P1171 售货员的难题 题目背景 数据有更改 题目描述 某乡有n个村庄(1<n<20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且 ...

  7. [LSGDOJ 1505]售货员的难题 状压DP

    题目描述 某 乡有n个村庄(1<n<15),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且A村 到B村与B村到A村的路大多不同.为了提高 ...

  8. P1171 售货员的难题--搜索(剪枝)

    题目背景 数据有更改 题目描述 某乡有nn个村庄(1<n \le 201<n≤20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)s(0<s ...

  9. 洛谷 P1171 售货员的难题 【状压dp】

    题目描述 某乡有n个村庄(1<n<20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)是已知的,且A村到B村与B村到A村的路大多不同.为了提高效率 ...

随机推荐

  1. C#中分部类和分部方法的应用

    本篇文章介绍了,C#中分部类和分部方法的应用.需要的朋友参考下     分部类(Partial Class)在C#2.0引入,分部方法(Partial Method)在C#3.0引入,这两个语法特性都 ...

  2. FPGA原型验证

    为什么要做FPGA原型验证? FPGA原型验证可以在IC流片前对芯片功能和性能做出评估,同时,可以给软件设计人员提供验证平台.所有的设计,无论是SOC还是ASIC都需要被验证(功能和时序验证),以确保 ...

  3. 磁盘格式化mke2fs

    -b 设置每个块的大小,当前支持1024,2048,40963种字节 -i 给一个inode多少容量 -c 检查磁盘错误,仅执行一次-c时候,会进行快速读取测试:-c -c会测试读写,会很慢 -L 后 ...

  4. linux系统中文件的几种类型

    Linux系统是以文件的形式来进行管理的.Linux文件类型常见的有:普通文件.目录.字符设备文件.块设备文件.符号链接文件等,如果想了解这方面知识的弟兄,就进来了解了解. Linux系统不同于win ...

  5. PMP项目管理学习笔记(3)——过程框架

    所有项目,不论大小,都可以分解为过程组: 如果项目规模很大,可以分阶段管理,每个阶段都要经过上面的五个过程组,从启动到收尾. 阶段的类型: 顺序阶段: 一个阶段完成后进入下个阶段. 重叠阶段: 有时需 ...

  6. get log

    C:\Users\wb_changxiang.chen\Desktop\get_log_adb.py #! /usr/bin/env pythonimport osimport sysimport t ...

  7. softmax_regression完成mnist手写体数据集的识别

    ---恢复内容开始--- import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnis ...

  8. Android开发案例 - 淘宝商品详情【转】

    http://erehmi.cnblogs.com/ 所有电商APP的商品详情页面几乎都是和淘宝的一模一样(见下图): 采用上下分页的模式 商品基本参数 & 选购参数在上页展示 商品图文详情等 ...

  9. react笔记汇总

    1.什么是React? a.React 是一个用于构建用户界面的 JAVASCRIPT 库. b.React主要用于构建UI,很多人认为 React 是 MVC 中的 V. c.React 起源于 F ...

  10. 牛客网数据库SQL实战 1-11

    1. 查找最晚入职员工的所有信息 CREATE TABLE `employees` ( `emp_no` ) NOT NULL, `birth_date` date NOT NULL, `first_ ...