hdu 3001 Travelling (TSP问题 )
Travelling
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3905 Accepted Submission(s): 1234
city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So
he turns to you for help.
a and b and the cost is of course c.Input to the End Of File.
2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10
100
90
7
DP+状态压缩:每一个点最多仅仅能经过2次,考虑用3进制存储状态;
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 12
#define M 59050
#define LL long long
const int inf=0x1f1f1f1f; //注意初始化值
int tri[N]= {0,1,3,9,27,81,243,729,2187,6561,19683,59049};
int g[N][N];
int dig[M][N]; //dig[i][j]记录I状态下J点是否出现,出现几次
int dp[M][N]; //dp[s][j] 在状态s下,以j为终点的最短距离
void inti() //求出每一个状态s相应的3进制位的信息
{
int i,j,t;
for(i=1;i<M;i++)
{
for(t=i,j=1;j<=10;j++)
{
dig[i][j]=t%3; //求出该状态下到达每一个的城市次数
t/=3;
if(!t) break;
}
}
}
int main()
{
int i,j,a,b,c;
int n,m,s;
inti();
while(scanf("%d%d",&n,&m)!=-1)
{
memset(g,inf,sizeof(g));
memset(dp,inf,sizeof(dp));
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=min(c,g[a][b]);
}
for(i=1;i<=n;i++) //起始状态。能够任一城市为起点。
dp[tri[i]][i]=0; //距离自然初始化为0
int ans=inf;
for(s=1;s<tri[n+1];s++) //在s状态以i为终点时更新其它状态的值
{
int f=1;
for(i=1;i<=n;i++)
{
if(dig[s][i]==0) //推断当前状态S下,每一个城市是否都已到达
f=0;
if(dp[s][i]==inf)
continue;
for(j=1;j<=n;j++) //dp[s][i]状态到dp[s+tri[j]][j]状态
{
if(g[i][j]==inf||i==j||dig[s][j]>=2)
continue;
int news=s+tri[j];
dp[news][j]=min(dp[news][j],dp[s][i]+g[i][j]);
}
}
if(f)
for(i=1;i<=n;i++)
ans=min(ans,dp[s][i]);
}
if(ans==inf)
ans=-1;
printf("%d\n",ans);
}
return 0;
}
</pre><p></p><p></p><p><span style="font-size:18px; color:#33ccff">bfs+状态压缩:</span></p><p><span style="color:rgb(51,204,255); font-size:18px">開始时把每个点都入队,模拟3进制处理每个状态,最后+优化。 </span></p><p></p><pre code_snippet_id="479354" snippet_file_name="blog_20141004_2_7195338" name="code" class="cpp">#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define N 12
#define LL long long
const int inf=0x3fffffff;
int g[N][N];
int n,m,ans;
int mark[N][60000];
struct node
{
int x,t,s,cnt; //位置、时间、状态、个数
friend bool operator<(node a,node b)
{
return a.t>b.t;
}
};
int gettmp(int x,int k) //得到X在3进制下的第K位是多少
{ //推断该点是否经过了。经过了几次
int t;
while(x)
{
t=x%3;
k--;
if(k==0)
break;
x/=3;
}
return k?0:t;
}
void inti() //初始化数组
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=0;j<(int)pow(3,n);j++)
mark[i][j]=inf;
}
}
void bfs()
{
int i;
priority_queue<node>q;
node cur,next;
for(i=1;i<=n;i++)
{
cur.x=i;
cur.s=pow(3,(i-1));
cur.t=0;
cur.cnt=1;
q.push(cur);
mark[i][0]=0;
}
while(!q.empty())
{
cur=q.top();
q.pop();
for(i=1;i<=n;i++)
{
if(g[cur.x][i]==inf) //此路不通
continue;
next.cnt=cur.cnt;
next.s=cur.s;
next.t=cur.t+g[cur.x][i];
if(ans<next.t) //优化非常重要
continue;
next.x=i;
int t=gettmp(next.s,i); //该点经过了几次,
if(t>=2) //经过2次后就不能走了
continue;
next.s+=pow(3,(i-1)); //该点经过次数加一
if(t==0) //经过一个新景点
{
next.cnt++;
if(next.cnt==n)
{
ans=min(ans,next.t);
continue;
}
}
if(next.t<mark[i][next.s])
{
mark[i][next.s]=next.t;
q.push(next);
}
}
}
}
int main()
{
int a,b,c,i,j;
while(scanf("%d%d",&n,&m)!=-1)
{
for(i=0;i<=n;i++)
for(j=1;j<=n;j++)
g[i][j]=(i==j? 0:inf);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=min(g[a][b],c);
}
ans=inf;
inti();
bfs();
if(ans==inf)
ans=-1;
printf("%d\n",ans);
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
hdu 3001 Travelling (TSP问题 )的更多相关文章
- HDU 3001 Travelling:TSP(旅行商)【节点最多经过2次】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意: 有n个城市,m条双向道路,每条道路走一次需要花费路费v.你可以将任意一个城市作为起点出发 ...
- HDU 3001 Travelling(状态压缩DP+三进制)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上 ...
- 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(状态压缩 三进制)
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,3进制)
题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...
- HDU 3001 Travelling 3进制状压dp
题意:10个点,若干条边,边有花费,每个点最多走两次,求走过所有点,花费最少 分析:因为每个点最多走两次,所以联想到3进制,然后枚举状态,就行了(我也是照着网上大神的代码写的) #include &l ...
- HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二
终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...
- Hdu 3001 Travelling 状态DP
题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进 ...
随机推荐
- python学习笔记之一:列表与元组
最近在看<python基础教程>(基于python2.x),下面总结一下第二章列表与元组的知识: 在这章中引入了数据结构的概念.数据结构是通过某种方式组织在一起的数据元素的集合.在pyth ...
- swift学习笔记(六)析关闭过程和使用分配给属性的默认值
一.通过关闭和功能的默认实现财产值 当存储属性默认值需要定制,能为客户提供通过关闭或全局函数的自定义默认值. 注意:全局函数的结构,和枚举使用keywordstatic大喊 用classkeyw ...
- Ubuntu14.04 用 CrossOver 安装 TMQQ2013
Crossover 是 wine 的优化+商业版本号 , 免去了wine的繁琐配置,让Ubuntu安装windows软件很easy..... 部分移植的软件还有官方的维护,执行效果也比較好..... ...
- 我的CSDN之路
经营CSDN博客刚满一年,能够说CSDN给我们带来了非常大的帮助,这一年里CSDN见证了我们的成长.以下两篇博客就是我这一年在CSDN的缩影. 这篇是我一年前写的,那时候刚申请CSDN不久:http: ...
- PM俱乐部之旅7-弱活着
有些人认为,最终我们放松一点时间,有意想不到的事情发生--公司组织结构调整. 公司由于业务范围调整,所以要进行对应的组织结构调整.PMO部门也随之重组,项目经理俱乐部的活动改成项目交流会,请项目 ...
- 解决Ubuntu和Windows该文件乱码问题
1.转换文件内容编码 Windows在自然纯文本文件.当中国作为编码GBK,在Ubuntu下乱码,可以使用iconv命令转换: iconv -f gbk -t utf8 source_fi ...
- CentOS6.5 Nginx优化编译配置
说到Nginx,它真的算是我在运维工作中的好朋友,它优异的性能和极高的工作效率实在是让人大爱,来自internet的报告称其epoll模型能够支持高达50000个并发连接数. Epoll[维基百科]: ...
- Linux System Programming note 8 ——File and Directory Management
1. The Stat Family #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> ...
- Threejs 它可以在建立其内部房间效果可见
Threejs 中建立可看到其内部的房间效果 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协 ...
- 同TextView在不同的显示内容
首先,请原谅我不能命名文章.. . 我们不能准确地表达你说说什么什么,真正急着赶智商. 直接在地图上 如图所看到的显示的是两个textview 第一个实现的是,在同一个textview中给不同内容赋予 ...