HDU 3001 Travelling (状压DP,3进制)
题意:
给出n<=10个点,有m条边的无向图。问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用?
思路:
本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示,3进制可以先将表打出来。在走的时候注意只能走2次,其他的和普通的TSP状压DP是一样的。注意点:重边,自环等等,老梗了。
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
int g[N][N], dp[][N], up[N], bit[N]; int decode(int s)//将状态s解码
{
int cnt=;
for(int i=; s; i++)
{
bit[i]=s%;
s/=;
if(bit[i]) cnt++;
}
return cnt;
} int cal(int n)
{
memset(dp,0x3f,sizeof(dp));
int ans=INF;
for(int i=; i<=n; i++) dp[up[i-]][i]=;//先将每个起点设为0,并不影响结果
for(int s=; s<=up[n]; s++)
{
int cnt=decode(s);//cnt表示已经遍历的点数
for(int i=; i<=n; i++) //枚举中间点
{
if( bit[i]> ) //确保已经遍历过i点
{
for(int j=; j<=n; j++) //枚举终点
{
if( bit[j]== ) continue; //已经走过了2次
bool flag=cnt==n?true:false;//为了更新答案
if( bit[j]==&&cnt+==n ) flag=true;
int &q=dp[s+up[j-]][j];
if( q>dp[s][i]+g[i][j] ) q=dp[s][i]+g[i][j];
if(flag) ans=min(ans, q);
}
}
}
}
return ans;
} void init() //3进制先打表
{
int a=;
up[]=;
for(int i=; i<N; i++)
{
up[i]=a;
a*=;
}
} int main()
{
//freopen("input.txt","r",stdin);
init();
int n, m, a, b, c;
while(~scanf("%d%d",&n,&m)) //每个点至多可走2次
{
memset(g,0x3f,sizeof(g));
for(int i=; i<=n; i++) g[i][i]=;
for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=min(g[a][b],c);
}
if(n==)
{
puts("");
continue;
}
int ans=cal(n);
printf("%d\n", ans==INF?-:ans);
}
return ;
}
AC代码
HDU 3001 Travelling (状压DP,3进制)的更多相关文章
- HDU 3001 Travelling ——状压DP
[题目分析] 赤裸裸的状压DP. 每个点可以经过两次,问经过所有点的最短路径. 然后写了一发四进制(真是好写) 然后就MLE了. 懒得写hash了. 改成三进制,顺利A掉,时间垫底. [代码] #in ...
- HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二
终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...
- HDU 3001 Travelling (状压DP + BFS)
题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次.现在给出城市之间的来往路费,他可以选择任意一个点为起点. 问逛遍所有城市的最低路费是多少. 析:用三进制表示每个城市的访问 ...
- hdu 3001(状压dp, 3进制)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 由于本题中一个点最多能够访问2次,由此可以联想到3进制; visited[i][j]表示在状态i ...
- HDU3001 Travelling —— 状压DP(三进制)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3001 Travelling Time Limit: 6000/3000 MS (Java/ ...
- HDU 4284Travel(状压DP)
HDU 4284 Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...
- HDU 4336 容斥原理 || 状压DP
状压DP :F(S)=Sum*F(S)+p(x1)*F(S^(1<<x1))+p(x2)*F(S^(1<<x2))...+1; F(S)表示取状态为S的牌的期望次数,Sum表示 ...
- POJ1185 状压dp(二进制//三进制)解法
很显然这是一道状压dp的题目 由于每个最优子结构和前两行有关,一个显而易见的想法是用三维dp[i][j][k]用来记录在第i行下为j状态,i - 1行为k状态时的最大值,然而dp[100][1 < ...
- HDU - 5117 Fluorescent(状压dp+思维)
原题链接 题意 有N个灯和M个开关,每个开关控制着一些灯,如果按下某个开关,就会让对应的灯切换状态:问在每个开关按下与否的一共2^m情况下,每种状态下亮灯的个数的立方的和. 思路1.首先注意到N< ...
- HDU3001 Travelling 状压DP
哭瞎啊,每一个城市能够经过至多两次,但没有要求必须经过两次.想用 两个状压来乱搞搞.结果自觉得会T.结果 WA了,搞了一下午.没想到用三进制啊.智商捉急,參考了 http://blog.csdn.ne ...
随机推荐
- Oracle 11gr2的完全卸载
Oracle 11gr2的完全卸载方式与前些版本有了改变,运行D:\app\Administrator\product\11.2.0\dbhome_1\deinstall的deinstall.bat批 ...
- Json文件转Excel
先创建一个web项目,在根目录放置需要转换的json文件,直接读取静态Json文件加载数据进行转换,代码如下: string Json = string.Empty; List<object&g ...
- Git入门 时光穿梭鸡 版本回退 工作区 暂存区
分布式集中式 CVS及SVN都是集中式的版本控制系统 , 而Git是分布式版本控制系统 集中式版本控制系统,版本库是集中存放在中央服务器的, 而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得 ...
- unite2017《Unity企业级支持案例与分析》
在今天举办的Unite2017开发者大会上,Unity大中华区技术支持总监张黎明以"Unity企业级支持案例与分析"为主题进行了分享. 以下为演讲实录: 张黎明:非常感谢大家来参加 ...
- Linux 中 ip netns 命令
通过 ip netns help 可以查看所有关于ip netns的命令: network namespace 在逻辑上是网络堆栈的一个副本,它有自己的路由.防火墙规则和网络设备. ip netns ...
- 用Java创建JMeter变量 - 终极指南
了解如何在Java中创建不同类型的JMeter变量,不同变量类型的详细信息以及如何避免错误. 在Apache JMeter™中编写负载或功能测试涉及使用不同类型的变量.变量有多种用途,例如,在以下情况 ...
- 浅谈最近公共祖先(LCA)
LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. (来自百度百科) 一.倍增求LCA 预处理出距点u距离为2^0,2^1,2 ...
- hdu4570-区间dp
这道题的题意不是一般的难懂啊,各种查字典都没理解,还是没忍住去看了别人的博客,没想到题很简单,1-n内划分若干个区间,使的每个区间和最小,每个区间的区间和是:区间开头的数*2^区间长度. 区间dp # ...
- jdbc查询
import java.util.ArrayList; import java.util.List; import org.springframework.jdbc.core.BeanProperty ...
- JavaScript实现一个简单的密码输入功能
常见的密码输入框当输入字符后会被替换成‘*’,而且旁边会有个小眼睛可以查看原本的字符,虽然input标签有这个功能,但这只是自己正在看正则表达式的时候突然想到的,就当做个练习,自己手动实现下: < ...