<题目链接>

题目大意:

给出n个点和m条边,求经过所有点所需的最小花费,每个点最多经过两次。

解题分析:

TSP问题类型,由于此题每个点有三种状态,所以采用三进制状态压缩,0、1、2 分别代表经过这个点的次数,然后就与TSP的dp解法类似,dp[i][j]代表状态为i,以 j 城市作为旅途的最后一个点所需的最小花费 。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
int dp[60000][11];///dp[i][j]表示i状态下以j结尾的最短步数
int three[11];///three[i]表示3的i次方是多少
int digit[60000][11];///digit[i][j]表示状态i的第j位是什么数字(0,1,2)
int edge[15][15]; //记录两点之间路径的值
int n,m;
const int INF=0x3f3f3f3f; void init()
{
three[0]=1;
for(int i=1; i<11; i++)
three[i]=three[i-1]*3; for(int i=0; i<three[10]; i++)
{
int tem=i; //tem代表当前的状态序号
for(int j=0; j<10; j++)
{
digit[i][j]=tem%3; //将状态压缩的当前状态的每一位的实际情况计算出来
tem/=3;
}
}
} int main()
{
init(); //将每一状态的所有点对应实际情况预先打表处理
while(~scanf("%d%d",&n,&m))
{
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
edge[i][j]=INF; //两点距离初始化,为后面的去重做准备 for(int i=0;i<three[n];i++)
for(int j=0; j<n; j++)
dp[i][j]=INF; //因为最后要求的是最短距离,所以初始化为INF while(int i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
edge[a-1][b-1]=edge[b-1][a-1]=min(c,edge[a-1][b-1]); //去重
}
for(int i=0;i<n; i++)
dp[three[i]][i]=0; //dp的初始化,将起点都找出来 ,所有点的标号为0~n-1 int ans=INF;
for(int j=0; j<three[n]; j++) //枚举所有状态
{
bool flag=1;
for(int i=0;i<n; i++)
{
if(digit[j][i]==0)flag=0;///只要三进制数中存在一个0,那么就说明还有点没有遍历完,就不能当做最终答案来求,即筛选掉那些不符合题意的状态
if(dp[j][i]!=INF)
for(int k=0;k<n;k++)
if(edge[i][k]!=INF&&digit[j][k]!=2)///注意这个digit[j][k]!=2,因为如果j状态在k点已经走过两次了显然是不能继续往下走的
dp[j+three[k]][k]=min(dp[j][i]+edge[i][k],dp[j+three[k]][k]);
//更新加入edge[i][k]边的最小值,j+three[k]表示用当前状态j,加入edge[i][k]后,更新状态j+three[k]的值
}
if(flag)
for(int i=0; i<n; i++)
ans=min(ans,dp[j][i]);
}
if(ans>=INF)
printf("-1\n");
else
cout<<ans<<endl;
}
return 0;
}

  

2018-09-07

最新文章

  1. 剖析并利用Visual Studio Code在Mac上编译、调试c#程序
  2. 一起来做webgame,《Javascript蜘蛛纸牌》
  3. json转实体类
  4. Python Twisted、Reactor
  5. Java集合中List的用法
  6. 浅析Android中的消息机制(转)
  7. javascript 拷贝
  8. FrameworkElement.Name与x:Name
  9. PHP获取客户端和服务器IP地址
  10. WPF 打开文件 打开路径对话框
  11. 移动端使用rem方法
  12. 修改ElementUI源码实践
  13. [AHOI2001]彩票摇奖
  14. Java_异常处理
  15. Linux代理服务器—squid正向代理实验
  16. Virtual DOM 和 diff 算法
  17. 20180820 JS 片段
  18. ZZCMS8.2 用户密码重置漏洞
  19. Instant low voltage or power off to make computer power burn down
  20. python在windows系统中打印中文乱码

热门文章

  1. Confluence 6 注册外部小工具
  2. Confluence 6 自定义 Decorator 模板的宏和针对高级用户
  3. verilog 异步复位代码
  4. day04 运算符 流程控制 (if while/of)
  5. 条件为空的sql你们写过么 (我也是醉了碰到了这种需求,当时还真有点o((⊙﹏⊙))o懵逼.jpg)
  6. NMT 机器翻译
  7. 第一周学习总结-Java
  8. .tar.xz文件的解压方法
  9. 卸载列表信息——Uninstall注册表
  10. 安装 jpegtran-cffi 使用 from jpegtran import JPEGImage