HDU 3001 Travelling:TSP(旅行商)【节点最多经过2次】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001
题意:
有n个城市,m条双向道路,每条道路走一次需要花费路费v。你可以将任意一个城市作为起点出发,然后遍历每一个城市,并保证同一个城市最多经过2次。问你遍历这些城市的最小费用是多少。
题解:
传统的TSP问题中,每个城市只能经过一次,做法为三重for循环,分别枚举城市的state、现在所处位置i、下一步要到达的城市j。
核心Code:
memset(dp,-,sizeof(dp));
dp[<<start][start]=;
for(int state=;state<(<<n);state++)
{
for(int i=;i<n;i++)
{
if(dp[state][i]!=-)
{
for(int j=;j<n;j++)
{
if(i!=j && !((state>>j)&))
{
if(dp[state|(<<j)][j]==- || dp[state|(<<j)][j]>dp[state][i]+dis[i][j])
{
dp[state|(<<j)][j]=dp[state][i]+dis[i][j];
}
}
}
}
}
}
在这道题中,与传统TSP的唯一区别是每个城市最多经过的次数由1次变为了2次。那么表示每座城市的状态state也应该相应改为用三进制数表示,每一位上的数字代表对应城市已经经过的次数。
所以把所有的二进制改为三进制就好啦 ( ̄▽ ̄)~*
注:不用对于每一个起点分别求一次dp,会T。。。在开始要把所有的dp[update(0, i)][i] = 0
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#define MAX_N 15
#define MAX_S 60000
#define INF 100000000 using namespace std; const int POW[]={,,,,,,,,,,,,,,}; int n,m;
int a,b,v;
int ans;
int dis[MAX_N][MAX_N];
int dp[MAX_S][MAX_N]; void init()
{
for(int i=;i<n;i++)
{
for(int j=;j<n;j++)
{
dis[i][j]=INF;
if(i==j) dis[i][j]=;
}
}
} void read()
{
for(int i=;i<m;i++)
{
cin>>a>>b>>v;
dis[a-][b-]=min(dis[a-][b-],v);
dis[b-][a-]=min(dis[b-][a-],v);
}
} int query(int a,int k)
{
return a/POW[k]%;
} int update(int a,int k)
{
return a+POW[k];
} bool check(int state)
{
for(int i=;i<n;i++)
{
if(query(state,i)==) return false;
}
return true;
} void solve()
{
ans=INF;
memset(dp,-,sizeof(dp));
for(int i=;i<n;i++)
{
dp[update(,i)][i]=;
}
for(int state=;state<POW[n];state++)
{
for(int i=;i<n;i++)
{
if(dp[state][i]!=-)
{
for(int j=;j<n;j++)
{
if(i!=j && query(state,j)<)
{
int nex=update(state,j);
if(dp[nex][j]==- || dp[nex][j]>dp[state][i]+dis[i][j])
{
dp[nex][j]=dp[state][i]+dis[i][j];
}
}
}
if(check(state)) ans=min(ans,dp[state][i]);
}
}
}
} void print()
{
if(ans==INF) cout<<-<<endl;
else cout<<ans<<endl;
} int main()
{
while(cin>>n>>m)
{
init();
read();
solve();
print();
}
}
HDU 3001 Travelling:TSP(旅行商)【节点最多经过2次】的更多相关文章
- hdu 3001 Travelling (TSP问题 )
Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HDU - 3001 Travelling(三进制状压dp)
Travelling After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best ch ...
- hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp
题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...
- hdu 3001 Travelling(状态压缩 三进制)
Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 3001 Travelling (三进制)【状压dp】
<题目链接> 题目大意: 给出n个点和m条边,求经过所有点所需的最小花费,每个点最多经过两次. 解题分析: TSP问题类型,由于此题每个点有三种状态,所以采用三进制状态压缩,0.1.2 分 ...
- HDU 3001 Travelling(状态压缩DP+三进制)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上 ...
- HDU 3001 Travelling 3进制状压dp
题意:10个点,若干条边,边有花费,每个点最多走两次,求走过所有点,花费最少 分析:因为每个点最多走两次,所以联想到3进制,然后枚举状态,就行了(我也是照着网上大神的代码写的) #include &l ...
- Hdu 3001 Travelling 状态DP
题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进 ...
- HDU 3001 Travelling (三进制状态压缩 DP)
题意:有 n 个city,能够选择任一城市作为起点,每一个城市不能訪问超过2次, 城市之间有权值,问訪问所有n个城市须要的最小权值. 思路:由于每一个城市能够訪问最多两次,所以用三进制表示訪问的状态. ...
随机推荐
- 使用ReflectionToStringBuilder实现toString方法
使用ReflectionToStringBuilder实现toString方法 org.apache.commons.lang.builder.ReflectionToStringBuilder是co ...
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
StringBuilder.StringBuffer.String类之间的关系 java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,在上一篇博文中我 ...
- SQL 中 decode()函数
文本转自 FreeSpider的微博 今天看别人的SQL时看这里面还有decode()函数,以前从来没接触到,上网查了一下,还挺好用的一个函数,写下来希望对朋友们有帮助哈! decode()函数简介: ...
- 微信小程序的登陆流程详解
由于小程序的登陆和登陆状态维护流程比较复杂,需要客户端和服务器的数次交互以及服务器端的相应处理,很多同学都觉得比较麻烦,所以特别写下这篇博客为大家梳理一下微信的登陆流程,同时加深对微信小程序与登陆状态 ...
- jvm学习002 虚拟机类加载过程以及主动引用和被动引用
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 类从被加载到虚拟机内存中开始,到卸载出内存为 ...
- ASP.NET MVC HttpPostedFileBase文件上传
HttpPostedFileBase文件上传,支持多文件一次上传,如有图片,则支持略缩图保存 文件传输信息封装 /// <summary> /// 文件生成方式 /// </summ ...
- Android studio中找不到so文件的问题:java.lang.UnsatisfiedLinkError
解决Android studio中找不到so文件的问题:java.lang.UnsatisfiedLinkError 表示我们不编译jni代码,直接从libs里面复制so库 文件路径:app\buil ...
- Oracle和MySQL分组查询GROUP BY
Oracle和MySQL分组查询GROUP BY 真题1.Oracle和MySQL中的分组(GROUP BY)有什么区别? 答案:Oracle对于GROUP BY是严格的,所有要SELECT出来的字段 ...
- 为什么 1000 == 1000会返回false,100 == 100会返回true
给你们看一段神奇的代码 /*对这段代码可以提供如下解释 * 判断两个对象是否相等的是看两个对象的引用是否相同 如果相同那么就返回true否则返回false * Integer会对-128~127之间的 ...
- Hibernate--inverse属性与cascade属性
转载:http://www.cnblogs.com/otomedaybreak/archive/2012/01/17/2324772.html Hibernate 集合映射中,经常会使用到" ...