HDU3001 Travelling 状压DP
哭瞎啊,每一个城市能够经过至多两次,但没有要求必须经过两次。想用 两个状压来乱搞搞。结果自觉得会T。结果 WA了,搞了一下午。没想到用三进制啊。智商捉急,參考了
http://blog.csdn.net/lenleaves/article/details/7980955 这个博客
每一个城市能够经过1或2次。所以三进制能够代表全部状态了。接下来处理方式类似于二进制的,仅仅是没有了位运算一些推断跟预处理有点繁琐
方程dp[s][i] = min(dp[s][i] , dp[s - (s除去j剩下状态)][k] + dis[k][j]),
因为没有固定的出发点,所以也就没有固定的终点。所以要以不论什么城市为终点的可能都要枚举到
dp[i][j]代表i状态下以 j为终点的最小花费
转移方程就是 : i 状态以j为终点的递推为(i状态中不经过j位置的状态下以k为终点 + k到j所需距离).
#define MAXN 0x3f3f3f3f
int n,m;
int dp[100000 + 55][10 + 5];
int mp[10 + 5][10 + 5];
int s[59050][10 + 5];
void clear() {
for(int i=0;i<59050;i++) {
int tmp = i;
for(int j=1;j<=10;j++) {
s[i][j] = tmp%3;
tmp /= 3;
if(!tmp)break;
}
}
}
void init() {
memset(mp,0x3f3f3f3f,sizeof(mp));
memset(dp,0x3f3f3f3f,sizeof(dp));
}
bool input() {
while(scanf("%d %d",&n,&m) == 2) {
for(int i=0;i<m;i++) {
int u,v,val;
scanf("%d %d %d",&u,&v,&val);
if(val < mp[u][v]) {
mp[u][v] = val;
mp[v][u] = val;
}
}
return false;
}
return true;
}
void cal() {
if(n == 1) {puts("0");return ;}
int now[12];
now[0] = 0;
now[1] = 1;
for(int i=2;i<=11;i++)now[i] = 3 * now[i - 1];/*举出刚好仅仅过i位置的状态*/
for(int i=0;i<=n;i++)dp[now[i]][i] = 0;//边界值。仅仅经过i位置的状态再以i为终点耗费肯定为0
int ans = MAXN;
for(int i=0;i<now[n + 1];i++) {
bool flag = true;//标记推断是否訪问了全部的地方
for(int j=1;j<=n;j++) {/*枚举以j为终点*/
if(s[i][j] == 0) {flag = false;continue;}//i状态并没有经过j
for(int k=1;k<=n;k++) {
if(s[i][k] == 0)continue;/*i状态没有经过k*/
int tmp = i - now[j];//使得i状态中第j位置为0
dp[i][j] = min(dp[i][j],dp[tmp][k] + mp[k][j]);
/*i状态以j为终点的递推为(i状态中只是j位置的状态下以k为终点 + k到j所需距离)*/
}
}
if(flag)//若该状态下全部地方都訪问过了,就从以各个地方为终点的最佳方案中再取出最优的
for(int j=1;j<=n;j++)ans = min(ans,dp[i][j]);
}
if(ans == MAXN)puts("-1");
else printf("%d\n",ans);
}
void output() {
}
int main () {
clear();
while(true) {
init();
if(input())return 0;
cal();
output();
}
return 0;
}
HDU3001 Travelling 状压DP的更多相关文章
- HDU3001 Travelling —— 状压DP(三进制)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3001 Travelling Time Limit: 6000/3000 MS (Java/ ...
- HDU 3001 Travelling ——状压DP
[题目分析] 赤裸裸的状压DP. 每个点可以经过两次,问经过所有点的最短路径. 然后写了一发四进制(真是好写) 然后就MLE了. 懒得写hash了. 改成三进制,顺利A掉,时间垫底. [代码] #in ...
- hdu3001(状压dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意:n 个城市已经 m 条路 以及对应路费 c,要求遍历所有城市最少的路费,每个城市不能超过2 ...
- hdu3001(状压dp,三进制)
Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二
终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...
- HDU 3001 Travelling (状压DP + BFS)
题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次.现在给出城市之间的来往路费,他可以选择任意一个点为起点. 问逛遍所有城市的最低路费是多少. 析:用三进制表示每个城市的访问 ...
- Travelling(HDU3001+状压dp+三进制+最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目: 题意:n个城市,m条边,每条边都有一个权值,问你经过所有的城市且每条边通过次数不超过两次 ...
- hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp
题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...
- HDU 3001 Travelling (状压DP,3进制)
题意: 给出n<=10个点,有m条边的无向图.问:可以从任意点出发,至多经过同一个点2次,遍历所有点的最小费用? 思路: 本题就是要卡你的内存,由于至多可经过同一个点2次,所以只能用3进制来表示 ...
随机推荐
- Windows下修改oracle实例不随服务自动启动
设置Oracle Administration Assistant for Windows 开始->所有程序->Oracle - OraDb10g_home1->配置和移植工具-&g ...
- 《深入浅出MyBatis技术原理与实战》——1.简介,2.入门
1. 简介 Java程序都是通过JDBC连接数据库,但是只定义了接口规范,具体的实现交给各个数据库厂商去实现,因为每个数据库都有其特殊性.所以JDBC是一种桥接模式. 这里为什么说JDBC是一种桥接模 ...
- Search in Rotated Sorted Array I&&II——二分法
Search in Rotated Sorted Array I Suppose a sorted array is rotated at some pivot unknown to you befo ...
- QT中循环显示图片和简单的显示图片
请关注我的github https://github.com/linqiaozhou 以下实例代码不久后将会上传到我的github 这是我最近一个项目中的部分代码 //以下是简单的在QT中显示图片的代 ...
- jquery&javascript 跨域jsonp
$(function(){ $.ajax({ type: "get", async: false, url: "http://flightQuery.com/jsonp/ ...
- 视频H5のVideo标签在微信里的坑和技巧
随着 4G 的普遍以及 WiFi 的广泛使用,手机上的网速已经足够稳定和高速,以视频为主的 HTML5 也越来越普遍了,相比帧动画,视频的表现更加丰富,前段时间开发了一个以视频为主的移动端 HTML5 ...
- ExtJs之列表常用CRUD
前端代码: Ext.onReady(function(){ Ext.define('Person', { extend: 'Ext.data.Model', fields: [{name: 'id', ...
- 机房重构包图(从三层+实体到三层+实体+外观+工厂+接口+SQLHelper)
刚刚开始接触三层的时候,我只做了两个登录小窗体的例子.画了简单的包图,可以说,为后面机房重构留下了大量的工作(因为三层理解没有深度,也没有理解出自己的东西).不过,欠下的总要还的.在做机房重构的时候, ...
- codevs1033 蚯蚓的游戏问题 裸最小费用最大流,注意要拆点
因为蚯蚓走过的路径不能重合,所以把每个点拆成两个点,容量赋为1,保证不会走过相同的点,再加超级源点(程序中为1)和一个辅助点(程序中为2)容量赋为k来控制蚯蚓的数量,最后汇集到一个超级汇点上.做一遍最 ...
- 【模拟】Gym - 101190A - Abbreviation
让你把所有的“连续的仅有首字母大写的”词组用缩写表示,并且在后面用括号注明原词组. #include<cstdio> #include<cstring> using names ...