第一眼看到这题,哇,这不是我刚做完的题吗?大水题!然后







这题表面很水,实际上有点坑。

题意

求经过 $ 1 - n $(不能遗漏) 并且回到 $ 1 $ 的最短路。

在看这题之前我们可以来看下这题

最短Hamilton路

这道题的要求是我们要让每个点不重不漏的经过并且最终到达 $ n-1 $ 我们看数据范围,就可以直接状压dp,枚举状态。

由于题目已经给出最短路,便可以直接计算

#include<bits/stdc++.h>
using namespace std;
int n,a[30][30];
int f[1100000][30];
int main(){
scanf("%d",&n);
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
scanf("%d",&a[i][j]);
}
}
memset(f,0x3f,sizeof(f));
f[1][0]=0;
for(int i=1;i<(1<<n);++i){//状态
for(int j=0;j<n;++j){//终点
if((i>>j)&1){
for(int k=0;k<n;++k){//起点
if(((i>>k)&1)&&a[j][k]){//保证有路相通
f[i][j]=min(f[i][j],f[i^(1<<j)][k]+a[k][j]);//找没能达到j的
}
}
}
}
}
printf("%d",f[(1<<n)-1][n-1]);//最后在n-1
return 0;
}

那么我们回到这题,它给出每个点的边,最后都要经过,并且返回,仔细一想,不就是多了个最短路吗?直接跑一遍 $ floyd $ 枚举终点返回不就好了?

然后我就写下了这个代码

#include<bits/stdc++.h>
using namespace std;
const int INF=1<<30;
int n,m,T,dis[20][20];
int f[(1<<20)][20];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
if(n==1){
printf("0\n");
continue;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(i==j) dis[i][j]=0;
else dis[i][j]=INF;
}
}
for(int i=1;i<=m;++i){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
dis[x][y]=min(dis[x][y],z);
dis[y][x]=dis[x][y];
}
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
memset(f,0x3f,sizeof(f));
f[1][1]=0;
for(int i=1;i<(1<<n);++i){
for(int j=1;j<=n;++j){
if((i>>(j-1))&1){
for(int k=1;k<=n;++k){
if(((i>>(k-1))&1)&&(dis[j][k]!=INF)){
f[i][j]=min(f[i][j],f[i^(1<<(j-1))][k]+dis[j][k]);
}
}
}
}
}
int ans=1<<30;
for(int i=1;i<=n;++i){
ans=min(ans,f[(1<<n)-1][i]+dis[i][1]);
}printf("%d\n",ans);
}
return 0;
}

然后RE,后面问了乐老师,发现这个题会出现自环

if(n==1){
printf("0\n");
continue;
}

这个就是问题的关键所在,不能直接 $ continue $ 因为后面还有边没读进来,会导致RE。

然后我就这样写了一下

#include<bits/stdc++.h>
using namespace std;
const int INF=1<<30;
int n,m,T,dis[20][20];
int f[(1<<20)][20];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
for(int i=0;i<=n;++i){
for(int j=0;j<=n;++j){
if(i==j) dis[i][j]=0;
else dis[i][j]=INF;
}
}
for(int i=1;i<=m;++i){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
dis[x][y]=min(dis[x][y],z);
dis[y][x]=dis[x][y];
}
if(n==1){
printf("0");
continue;
}
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
memset(f,0x3f,sizeof(f));
f[1][1]=0;
for(int i=1;i<(1<<n);++i){
for(int j=1;j<=n;++j){
if((i>>(j-1))&1){
for(int k=1;k<=n;++k){
if(((i>>(k-1))&1)&&(dis[k][j]!=INF)){
f[i][j]=min(f[i][j],f[i^(1<<(j-1))][k]+dis[k][j]);
}
}
}
}
}
int ans=1<<30;
for(int i=1;i<=n;++i){
ans=min(ans,f[(1<<n)-1][i]+dis[i][1]);
}printf("%d\n",ans);
}
return 0;
}

听取 $ wa $ 声一片,后面自己看了下题解,觉得思路没问题,看着它把最大值都定义为 $ 0x3f3f3f3f $ 我就一改,然后它过了??

原因是两个最大值不一样导致 $ dp $ 过程中会出现错误,最后我改成了

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,T,dis[20][20];
int f[(1<<20)][20];
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
for(int i=0;i<=n;++i){
for(int j=0;j<=n;++j){
if(i==j) dis[i][j]=0;
else dis[i][j]=INF;
}
}
for(int i=1;i<=m;++i){
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
dis[x][y]=min(dis[x][y],z);
dis[y][x]=dis[x][y];
}
if(n==1){
printf("0\n");
continue;
}
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
memset(f,0x3f,sizeof(f));
f[1][1]=0;
for(int i=1;i<(1<<n);++i){
for(int j=1;j<=n;++j){
if((i>>(j-1))&1){
for(int k=1;k<=n;++k){
if(((i>>(k-1))&1)&&(dis[k][j]!=INF)){
f[i][j]=min(f[i][j],f[i^(1<<(j-1))][k]+dis[k][j]);
}
}
}
}
}
int ans=INF;
for(int i=1;i<=n;++i){
ans=min(ans,f[(1<<n)-1][i]+dis[i][1]);
}printf("%d\n",ans);
}
return 0;
}

然后终于 $ AC $,其实这道题本身不难,主要是在一些细节上的处理,在多组数据下暴露的很明显,平时写题细节方面还是要多多注意。

hdu 5418 题解的更多相关文章

  1. ACM: HDU 5418 Victor and World - Floyd算法+dp状态压缩

    HDU 5418 Victor and World Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%I64d & ...

  2. HDU - 5067 / HDU - 5418 TSP

    集合表示多用[0,n)表示方法 HDU - 5067 经典TSP,每个顶点恰经过一次最优 #include<bits/stdc++.h> #define rep(i,j,k) for(in ...

  3. HDU 5418 Victor and World(状压DP+Floyed预处理)

    Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Other ...

  4. HDU 5418 Victor and World 允许多次经过的TSP

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5418 bestcoder(中文): http://bestcoder.hdu.edu.cn ...

  5. hdu 5418 (Floyd+哈密顿) 飞向世界

    http://acm.hdu.edu.cn/showproblem.php?pid=5418 题目大意是城市的编号是1到n,给出m条路线,表示从a城市飞到b城市飞机要耗多少油,最后问飞机从1出发飞过所 ...

  6. HDU 5418 Victor and World (状态压缩dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 题目大意:有n个结点m条边(有边权)组成的一张连通图(n <16, m<100000 ...

  7. HDU 2023题解分析

    我想说这道题我还没弄明白我错哪了,交了20多遍一直都是Runtime Error,改了N次还是不对,后来搜了一下,说是数组开小了,又把数组开大,还不对,又改发现一个平均值求错,再改,还不对,洗洗睡吧. ...

  8. 2014年北京网络赛 Instrusive HDU 5040 题解 优先队列

    网赛的时候看了这道题,发现就是平常的那种基础搜索题. 由于加了一个特殊条件:可以一次消耗3秒或原地停留1秒. 那就不能使用简单的队列了,需要使用优先队列才行. 题意 告诉一副地图:一个起点,一个终点, ...

  9. BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)

    [题目链接]:pid=5418">click here~~ [题目大意]: 问题描写叙述 经过多年的努力,Victor最终考到了飞行驾照. 为了庆祝这件事,他决定给自己买一架飞机然后环 ...

随机推荐

  1. 2018-2019 20165226 Exp 8 Web基础

    2018-2019 20165226 Exp 8 Web基础 目录 一.实验内容说明及基础问题回答 二.实验过程 1.Web前端:HTML 2.Web前端j:avascipt 3.Web后端:MySQ ...

  2. 2018-2019-2 20165212《网络对抗技术》Exp9 Web安全基础

    2018-2019-2 20165212<网络对抗技术>Exp9 Web安全基础 基础问题回答 1.SQL注入攻击原理,如何防御? 原理:SQL注入,就是通过把SQL命令插入到Web表单递 ...

  3. postgresql 增量备份

    介绍: barman是postgresql备份还原的管理工具. 本文环境: 系统: centos6.6 PostgreSQL 9.3.9 barman-1.4.1-1.rhel6.noarch.rpm ...

  4. QTextToSpeech Win7奔溃

    在linux下,它是调用speech-dispatcher.在其它不同的平台上,调用各自平台的TTS引擎.所以在使用的时候,要确保本地的TTS引擎是可用的. 本地TTS引擎不可用可能会在声明QText ...

  5. QT文本转语音模块(TTS)QTextToSpeech

    QTextToSpeech是QT5.8以上的文本转语音模块. 使用方法: 在.pro工程文件中添加“QT += texttospeech”. 添加头文件 #include <QTextToSpe ...

  6. ubuntu16.04安装python3.7

    1.安装依赖包 sudo apt-get update sudo apt-get install build-essential python-dev python-setuptools python ...

  7. CMU Database Systems - Storage and BufferPool

    Database Storage 存储分为volatile和non-volatile,越快的越贵越小 那么所以要解决的第一个问题就是,如果尽量在有限的成本下,让读写更快些 意思就是,尽量读写volat ...

  8. vbs msgbox提示信息最前面显示

    msgbox strContent, vbOKOnly or vbExclamation or vbSystemModal,strTitle 提示框类型列表: 常数 值 描述 vbOKOnly 0 只 ...

  9. shell编程系列7--shell中常用的工具find、locate、which、whereis

    shell编程系列7--shell中常用的工具find.locate.which.whereis .文件查找之find命令 语法格式:find [路径] [选项] [操作] 选项 -name 根据文件 ...

  10. 使用SoapUI发送Post请求

    https://www.cnblogs.com/xiaowangzi1110/p/8544264.html 使用SoapUI发送Post请求 SoapUI作为一个开源的工具,其具备强大的功能.易用的界 ...