P1171 售货员的难题

题目背景

数据有更改

题目描述

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

输入输出格式

输入格式:

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

输出格式:

最短的路程。

输入输出样例

输入样例#1: 复制

  1. 3
  2. 0 2 1
  3. 1 0 2
  4. 2 1 0
输出样例#1: 复制

  1. 3

说明

输入解释

3 {村庄数}

0 2 1 {村庄1到各村的路程}

1 0 2 {村庄2到各村的路程}

2 1 0 {村庄3到各村的路程}

  1. /*
  2. 洛谷上只能到90分qwq
  3. */
  4. #include<iostream>
  5. #include<cstdio>
  6. #define maxn 20
  7. int n,num,head[maxn],ans=0x7fffffff;
  8. struct node{
  9. int to,pre,v;
  10. }e[maxn*maxn];
  11. bool vis[maxn];
  12. using namespace std;
  13. void Insert(int from,int to,int v){
  14. e[++num].to=to;
  15. e[num].v=v;
  16. e[num].pre=head[from];
  17. head[from]=num;
  18. }
  19. void dfs(int pos,int cnt,int dis){
  20. if(dis>=ans)return;
  21. if(dis+n-cnt+>=ans)return;
  22. for(int i=head[pos];i;i=e[i].pre){
  23. int to=e[i].to;
  24. if(to==&&cnt==n){
  25. ans=min(ans,dis+e[i].v);
  26. return;
  27. }
  28. if(vis[to])continue;
  29. vis[to]=;
  30. dfs(to,cnt+,dis+e[i].v);
  31. vis[to]=;
  32. }
  33. }
  34. int qread(){
  35. int i=;
  36. char ch=getchar();
  37. while(ch<''||ch>'')ch=getchar();
  38. while(ch<=''&&ch>=''){i=i*+ch-'';ch=getchar();}
  39. return i;
  40. }
  41. int main(){
  42. freopen("Cola.txt","r",stdin);
  43. n=qread();
  44. int x;
  45. for(int i=;i<=n;i++)
  46. for(int j=;j<=n;j++){
  47. x=qread();
  48. if(i!=j)Insert(i,j,x);
  49. }
  50. vis[]=;
  51. dfs(,,);
  52. printf("%d",ans);
  53. }

90分 搜索+剪枝

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. int n,map[][],all,dp[][<<],ans=0x7fffffff;
  6. int qread(){
  7. int i=;
  8. char ch=getchar();
  9. while(ch<''||ch>'')ch=getchar();
  10. while(ch<=''&&ch>=''){i=i*+ch-'';ch=getchar();}
  11. return i;
  12. }
  13. int main(){
  14. freopen("Cola.txt","r",stdin);
  15. //scanf("%d",&n);
  16. n=qread();
  17. all=(<<n)-;
  18. for(int i=;i<=n;i++)for(int j=;j<=n;j++)map[i][j]=qread();
  19. memset(dp,0x3f,sizeof(dp));
  20. dp[][]=;
  21. for(int i=;i<=n;i++)dp[i][<<(i-)]=map[][i];
  22. for(int s=;s<=all;s++){
  23. for(int i=;i<=n;i++)
  24. if(s&(<<(i-)))
  25. for(int j=;j<=n;j++)
  26. dp[i][s]=min(dp[i][s],dp[j][s^(<<(i-))]+map[j][i]);
  27. }
  28. for(int i=;i<=n;i++)ans=min(ans,dp[i][all]+map[i][]);
  29. printf("%d",ans);
  30. }

80分 状压+枚举

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define min(a,b) (a)>(b)?(b):(a)
  5. int n,map[][],all,dp[][<<],ans=0x7fffffff,bit[];
  6. int qread(){
  7. int i=;
  8. char ch=getchar();
  9. while(ch<''||ch>'')ch=getchar();
  10. while(ch<=''&&ch>=''){i=i*+ch-'';ch=getchar();}
  11. return i;
  12. }
  13. int main(){
  14. freopen("Cola.txt","r",stdin);
  15. //scanf("%d",&n);
  16. bit[]=;
  17. for(int i=;i<=;i++)bit[i]=bit[i-]<<;
  18. n=qread();
  19. all=(<<n)-;
  20. for(int i=;i<=n;i++)for(int j=;j<=n;j++)map[i][j]=qread();
  21. memset(dp,0x3f,sizeof(dp));
  22. dp[][]=;
  23. for(int s=;s<=all;s+=){
  24. for(int i=;i<=n;i++)
  25. if(dp[i][s]<=)
  26. for(int j=;j<=n;j++)
  27. if(!(s&bit[j]))
  28. dp[j][s|bit[j]]=min(dp[j][s|bit[j]],dp[i][s]+map[i][j]);
  29. }
  30. for(int i=;i<=n;i++)ans=min(ans,dp[i][all]+map[i][]);
  31. printf("%d",ans);
  32. }

100分 状压

洛谷P1171 售货员的难题的更多相关文章

  1. 洛谷 P1171 售货员的难题

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

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

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

  3. 洛谷P1171 售货员的难题【状压DP】

    题目描述 某乡有n个村庄(1 输入格式: 村庄数n和各村之间的路程(均是整数). 输出格式: 最短的路程. 输入样例: 3 0 2 1 1 0 2 2 1 0 输出样例 3 说明 输入解释 3 {村庄 ...

  4. 2018.07.18 洛谷P1171 售货员的难题(状压dp)

    传送门 感觉是一道经典的状压dp,随便写了一发卡了卡常数开了个O(2)" role="presentation" style="position: relati ...

  5. P1171 售货员的难题

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

  6. 洛谷 P1379 八数码难题 Label:判重&&bfs

    特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给 ...

  7. 【题解】P1171 售货员的难题

    Tags 搜索,状压​. 裸的旅行商问题 #include <stdio.h> #include <string.h> #define re register #define ...

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

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

  9. 洛谷P1379八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...

随机推荐

  1. Poj 1659 Distance on Chessboard(国际象棋的走子规则)

    一.Description 国际象棋的棋盘是黑白相间的8 * 8的方格,棋子放在格子中间.如下图所示: 王.后.车.象的走子规则如下: 王:横.直.斜都可以走,但每步限走一格. 后:横.直.斜都可以走 ...

  2. IAR常用快捷键及技巧

    1.复制和粘贴几行的部分代码 需求:有时候我们需要复制几行代码的后半部分,不需要复制前半部分.方法:按住Alt键,再用鼠标拖动就可以复制和粘贴后半部分 [END/2015-09-23] 2.复制一行 ...

  3. Python:内置函数zip()

    zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,然后返回一个可迭代的zip对象. 这个可迭代对象可以使用循环的方式列出其元素 若多个可迭代对象的长度不一致,则所返回的 ...

  4. Python:列表反序和解析

    1)列表反序 A.list.reverse():将列表反序: l = [1, 2, 3, 4, 5] print(l.reverse()) -->[5, 4, 3, 2, 1] B.l.[::- ...

  5. JVM插庄之一:JVM字节码增强技术介绍及入门示例

    字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...

  6. 事务之五:Spring @Transactional工作原理

    本文将深入研究Spring的事务管理.主要介绍@Transactional在底层是如何工作的. JPA(Java Persistence API--java持久层)和事务管理 很重要的一点是JPA本身 ...

  7. 7.JasperReports学习笔记7-applet打印

    转自:http://www.blogjava.net/vjame/archive/2013/10/12/404908.html 打包applet的class和所需的jar包,并加上数字签名 要运行打印 ...

  8. k8s 基础 k8s架构和组件

    k8s 的总架构图

  9. tomcat solr 限制ip

    <Context path="/solr" reloadable="false" docBase="/var/www"> < ...

  10. linux 安装输入法

    简述 Ubuntu16.04安装完后,和12.04以及14.04都不一样,并没有中文输入功能.于是搜索一些安装中文输入法的方法. 开始安装了ibus pinyin输入法,但是系统重启之后发现有些时候不 ...