三进制状态压缩DP(旅行商问题TSP)HDU3001
http://acm.hdu.edu.cn/showproblem.php?pid=3001
Travelling
can bring him to any 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.
there is a road between 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
题意:给出一个无向图,并给出路径及费用,问旅行完所有的节点需要的花费最少是多少(可以从任意一点出发,每个节点经过的次数不超过2次)
分析:对于只经过节点仅且一次的题目,很清楚用二进制dp,暴搜完所有的状态,而此题每个节点有三个状态,即没走过,走了一次,走了两次,所以用三进制表示,分别代表三种状态;用dp[i][j]表示经过节点j后到达状态i;当i状态满足所有位置没有0是,即每个点都至少经过了一次,就是一种情况,但不一定是最优情况所以要更新最小值;
程序:
#include"stdio.h"
#include"string.h"
#include"iostream"
#include"map"
#include"string"
#include"queue"
#include"stdlib.h"
#include"algorithm"
#include"math.h"
#define M 60001
#define eps 1e-10
#define inf 100000000
#define mod 100000000
#define INF 0x3f3f3f3f
using namespace std;
int dp[M][12],px[12],a[M][12],dis[12][12],path[M][12];
void init()
{
int i;
px[0]=1;
for(i=1;i<=10;i++)
px[i]=px[i-1]*3;
memset(a,0,sizeof(a));
for(i=0;i<px[10];i++)
{
int k=i,t=0;
while(k)
{
a[i][t++]=k%3;
k/=3;
}
}
}
int main()
{
init();
int n,m,i,j,k;
while(scanf("%d%d",&n,&m)!=-1)
{
memset(dis,INF,sizeof(dis));
for(i=1;i<=m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
u--;
v--;
if(dis[u][v]>c)
dis[u][v]=dis[v][u]=c;
}
memset(dp,INF,sizeof(dp));
memset(path,-1,sizeof(path));
for(i=0;i<n;i++)
{
dp[px[i]][i]=0;
path[px[i]][i]=-1;
}
int ans=INF;
int I,J;
for(i=1;i<px[n];i++)
{
int flag=1;
for(j=0;j<n;j++)
{
if(a[i][j]==0)
{
flag=0;continue;
}
int cur=i-px[j];
for(k=0;k<n;k++)
{
if(dp[i][j]>dp[cur][k]+dis[k][j])
{
dp[i][j]=dp[cur][k]+dis[k][j];
path[i][j]=k;
} }
}
if(flag)
{
for(j=0;j<n;j++)
{
if(ans>dp[i][j])
{
I=i;
J=j;
ans=dp[i][j];
} }
}
}
/*********路径**********/
/*printf("%d->",J+1);
for(k=path[I][J];k!=-1;k=path[I][k])
{
printf("%d->",k+1);
I=I-px[J];
J=k;
}
printf("\n");*/
/***********************/
if(ans<INF)
printf("%d\n",ans);
else
printf("-1\n");
}
return 0;
}
三进制状态压缩DP(旅行商问题TSP)HDU3001的更多相关文章
- hdu-3001 三进制状态压缩+dp
用dp来求最短路,虽然效率低,但是状态的概念方便解决最短路问题中的很多限制,也便于压缩以保存更多信息. 本题要求访问全图,且每个节点不能访问两次以上.所以用一个三进制数保存全图的访问状态(3^10,空 ...
- HDU 3001 Travelling (三进制状态压缩 DP)
题意:有 n 个city,能够选择任一城市作为起点,每一个城市不能訪问超过2次, 城市之间有权值,问訪问所有n个城市须要的最小权值. 思路:由于每一个城市能够訪问最多两次,所以用三进制表示訪问的状态. ...
- HDOJ-3001(TSP+三进制状态压缩)
Traving HDOJ-3001 这题考察的是状态压缩dp和tsp问题的改编 需要和传统tsp问题区分的事,这题每个点最多可以经过两次故状态有3种:0,1,2 这里可以模仿tsp问题的二进制压缩方法 ...
- BZOJ4479 [JSOI2013] 吃货jyy 解题报告(三进制状态压缩+欧拉回路)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4479 Description [故事背景]作为JSOI的著名吃货,JYY的理想之一就是吃 ...
- hdu4064 三进制状态压缩 好题!
还不太会做这类题,总之感觉有点难啊. 用深搜代替打表求出一行所有的可行状态,注意要进行剪枝 这是自己理解的代码,但是tle了 #include<bits/stdc++.h> using n ...
- 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 题目大意: 给一个矩阵 n*m (n m<=200),方格里如果是0~9表示通过它时要花 ...
- poj 2688 状态压缩dp解tsp
题意: 裸的tsp. 分析: 用bfs求出随意两点之间的距离后能够暴搜也能够用next_permutation水,但效率肯定不如状压dp.dp[s][u]表示从0出发訪问过s集合中的点.眼下在点u走过 ...
- HDU 3001【状态压缩DP】
题意: 给n个点m条无向边. 要求每个点最多走两次,要访问所有的点给出要求路线中边的权值总和最小. 思路: 三进制状态压缩DP,0代表走了0次,1,2类推. 第一次弄三进制状态压缩DP,感觉重点是对数 ...
- HDU 3001 Travelling(状态压缩DP+三进制)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上 ...
随机推荐
- json拼接转义符
//转义符替 function escapeReplace(Str) { var newStrJson = Str.replace(/\%/g, "%25"); newStrJso ...
- C语言写的trim()函数
C语言的标准库中缺少对字符串进行操作的trim()函数,使用起来有些不便,可以使用利用 strlen 和 isspace 函数以及指针来自己写一个. 1.strlen 函数 原型:extern int ...
- foreach、count、explode(对无限级分类的语法注释-显示无限级效果)
foreach ($array as $key => $value) foreach仅能用于数组. 每次循环中,当前单元的键名也会在每次循环中被赋给变量$key. 当前单元的值被赋给$value ...
- [转载]如何解决failed to push some refs to git
Administrator@PC-20150110FGWU /K/cocos2d/yc (master) $ git push -u origin master To git@github.com:y ...
- buildroot制作文件系统
/******************************************************************* * buildroot制作文件系统 * 使用buildroot ...
- 【Java面试题】25 同步和异步有何异同,在什么情况下分别使用他们?举例说明。
如果数据将在线程间共享.例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取. 当应用程序在对象上调用了一个需要花费很长时间 ...
- uniqid,md5,microtime
<?php header("content-type:text/html;charset=utf-8"); $str = uniqid(md5(microtime(true) ...
- 清理SYSAUX表空间的WRH$_LATCH_CHILDREN表
周六 被突然起来的短信 轰醒. 一看有63条短信. 都是来之与监控中的.有关表空间大小超过某个警戒值. 发现 SYSAUX表空间超过了15GB 通过以下代码查看SYSAUX表空间的功能占用情况 SEL ...
- ojdbc14.jar 放在kettle那个目录下面
\libext\edtftpj-1.4.5.jar \libext\firebirdsql-full.jar \libext\firebirdsql.jar \libext\gis-shape.jar ...
- DropDownList添加客户端下拉事件操作
如果要想给 DropDownList 服务器控件添加客户端下拉事件,我们可以强制给它添加 onchange 事件,尽管在控件中没有这个方法的提示.添加完这个事件还不能达到目的,还要设置 AutoPos ...