Travelling(spfa+状态压缩dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3001
Travelling
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5295 Accepted Submission(s): 1718
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10
90
7
题意:一个地图可以从任意一个地点出发,到达遍历所有的点,每个点最多可以被访问2次,问这样遍历所有的点的最小边权和是多少。
题解:观察这个题的数据范围是10,而且要求每个点有3个状态:未被访问,被访问1次,被访问2次。是一个类似于汉密顿的问题(汉密顿问题是每个点经过且只经过一次)
考虑用状态压缩dp来写,但是一般的状态压缩是用0,1表示访问和未访问两个状态,所以用一个二进制数来表示这个地图的某个状态。而这个题是一个点有三个状态,未被访问,被访问一次,被访问2次。所以自然的想到用一个三进制数来表示,集合的运算完全类比于二进制的情况。
参见http://www.cnblogs.com/shanyr/p/4827563.html 的spfa思路
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define N 11
#define INF 0x7f7f7f7f//注意memset里的0x7f的值在int中是0x7f7f7f7f int mp[N][N];
bool vis[][N];
int dp[][N];
queue<pair<int,int> > q;
bool ch(int s, int n)
{
for(int i = ; i < n; i++) {
if(s% == ) return false;
s /= ;
}
return true;
}//检验最后的这个状态中是否是每个点都访问过
int main()
{
int n , m ;
while(~scanf("%d%d",&n,&m))
{
memset(vis,,sizeof(vis));
memset(dp,0x7f,sizeof(dp));
memset(mp,0x7f,sizeof(mp));
for(int i = ;i < n ;i++)
mp[i][i] = ;
dp[][] = ;
vis[][] = ;
q.push(make_pair(,));
for(int i = ; i < n; i++){
dp[(int)(pow(, i))][i] = ;
q.push(make_pair(pow(, i), i));
}
int u, v , d;
for(int i = ; i < m ; i++)
{
scanf("%d%d%d",&u,&v,&d);
u--,v--;
mp[u][v] = mp[v][u] = min(mp[u][v],d);
}
int tm = pow(,n)-;
while(!q.empty())
{
int s = q.front().first;
int u = q.front().second;
q.pop();
vis[s][u] = ;
int cur = s, ss;
for(int i = ;i < n ; i++)
{
int bt = cur % ;
cur /= ;//因为要考虑到没有用的数,及这个位置已经是2了就要在这个位置的下一位考虑了
if(bt < ) {
ss = s + pow(, i);
if(dp[ss][i]>dp[s][u]+mp[i][u]){
dp[ss][i] = dp[s][u] + mp[i][u];
if(vis[ss][i] == ){
vis[ss][i] = ;
q.push(make_pair(ss,i));
}
}
}
}
}
//for(int i = 0; i < pow(3, n); i++)
// for(int j = 0; j < n; j++)
// printf("%d %d : %d\n", i, j, dp[i][j]);
int ans = INF;
for(int s = ; s <= tm; s++)
for(int i = ;i < n ;i++)
if(ch(s, n)) ans = min(ans,dp[s][i]);
if(ans==INF) printf("-1\n");
else printf("%d\n",ans);
}
return ;
}
Travelling(spfa+状态压缩dp)的更多相关文章
- Victor and World(spfa+状态压缩dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/ ...
- HDU 3001 Travelling(状态压缩DP+三进制)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上 ...
- HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA
状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 当中k和l是对j的一个划分 依照边进行松弛 dp[i][j] ...
- hdu 4856 Tunnels 状态压缩dp
Tunnels Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- [转]状态压缩dp(状压dp)
状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...
- BZOJ1294 洛谷P2566 状态压缩DP 围豆豆
传送门 题目描述 是不是平时在手机里玩吃豆豆游戏玩腻了呢?最近MOKIA手机上推出了一种新的围豆豆游戏,大家一起来试一试吧游戏的规则非常简单,在一个N×M的矩阵方格内分布着D颗豆子,每颗豆有不同的分值 ...
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- [知识点]状态压缩DP
// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...
随机推荐
- Handler的解析和使用
1.handler为android中多线程间通信的一种机制, @1android中只允许在UI线程(主线程)操作或改变UI,其他线程不能操作UI. @2其他线程有刷新UI的需要,所以得告诉UI线程,这 ...
- python 字符串中的%s与format
你可以选择字符串拼接,你也可以选择使用%s或者是format,下面简单介绍一下它们的使用方法: # 在字符串后面跟%,然后后面加上要被替换的值 print('I like %s' % 'apples' ...
- 1.QT开发第一个程序
Ubuntu16.04安装QT5.8.0:http://www.cnblogs.com/dotnetcrazy/p/6725945.html QT5.8支持中文输入法(附带老版本的解决+不理想的情况解 ...
- js获取手机屏幕宽度、高度
网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...
- centos 系统日志
Linux系统日志主要有三类:连接时间日志.进程统计日志和错误日志 连接时间日志 连接时间日志由多个程序执行,把记录写入到/var/og/wtmp和/var/run/utmp.ogin等程序更新wtm ...
- 小谈SQL表的连接
简述SQL连接 SQL连接呢,主要分为以下几种内连接,左连接,右连接,全连接(当然还有很多官方的说法,这里就讲讲最常用的). 既然都叫连接了,那至少要有两个对象,也就是说,至少要有两个表,要怎么样的表 ...
- Git与GitHub学习笔记(八)git如何同时同步提交到码云和GitHub上
前言: 今天github push代码一直push不上去,打算就备份一份代码带国内开源码云上. Github容易出现的情况是: 国内访问速度比较慢, 如果被墙掉的话,就直接没发使用了 如果开源个PHP ...
- Java数组的创建和初始化
我们说到数组,可能有的人就会比较害怕了,其实,数组只是把对象序列(很多个对象)或者基本类型序列(很多个基本类型)放在一起而已.数组是通过方括号下标操作符[]来定义和使用的.如果要定义,创建一个数组,只 ...
- 通俗易懂的信息熵与信息增益(IE, Information Entropy; IG, Information Gain)
信息熵与信息增益(IE, Information Entropy; IG, Information Gain) 信息增益是机器学习中特征选择的关键指标,而学习信息增益前,需要先了解信息熵和条件熵这两个 ...
- [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等
本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...