题目链接

题意

给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次)。

思路

状态表示、转移及大体思路poj 3311 Hie with the Pie 经过所有点(可重)的最短路径 floyd + 状压dp 相同。

但,因为是每个点 至多可以经过两次,所以应该用 三进制 来表示状态。

因为三进制不能直接通过移位来表示,所以要 预处理 出每个数字\(state\)的三进制表示中每一位\(i\)上的值\(dig[state][i]\).

注意:该题数据中有 重边

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define inf 0x3f3f3f3f
#define maxs 60010
#define maxn 12
using namespace std;
typedef long long LL;
int power3[] = {1, 3, 9,27,81,243,729,2187,6561,19683,59049};
int n, m, dp[maxs][maxn], dig[maxs][maxn], dis[maxn][maxn];
bool vis[maxs][maxn];
void init() {
F(i, 0, power3[n]) {
int state = i, cnt = 0;
while (state) {
dig[i][cnt++] = state%3;
state /= 3;
}
}
}
int dfs(int state, int p) {
if (state == power3[p]) return 0;
if (vis[state][p]) return dp[state][p];
vis[state][p] = true;
int sta = state - power3[p], ans = inf;
F(i, 0, n) {
if (dis[i][p] && dig[state][i] && (i!=p || (i==p&&dig[state][i]==2))) ans = min(ans, dfs(sta, i)+dis[i][p]);
}
return dp[state][p] = ans;
}
inline bool check(int state) {
F(i, 0, n) if (!dig[state][i]) return false;
return true;
}
void work() {
memset(dp, 0, sizeof dp); memset(vis, 0, sizeof vis); memset(dis, 0, sizeof dis);
init();
F(i, 0, m) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w); --u, --v;
if (dis[u][v]==0 || w<dis[u][v]) dis[u][v] = dis[v][u] = w;
}
int lim = power3[n]-1, ans = inf;
F2(i, lim>>1, lim) {
if (!check(i)) continue;
F(j, 0, n) {
ans = min(ans, dfs(i, j));
}
}
printf("%d\n", ans==inf?-1:ans);
}
int main() {
while (scanf("%d%d", &n,&m) != EOF) work();
return 0;
}

hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp的更多相关文章

  1. HDU 3001 三进制状压DP

    N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方程: dp[i+b[k]][k]= ...

  2. HDU - 3001 Travelling(三进制状压dp)

    Travelling After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best ch ...

  3. HDU 3001 三进制 状压dp

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. Travelling (三进制+状压dp)

    题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read(){ ,f= ...

  5. 三进制状压 HDOJ 3001 Travelling

    题目传送门 题意:从某个点出发,所有点都走过且最多走两次,问最小花费 分析:数据量这么小应该是状压题,旅行商TSP的变形.dp[st][i]表示状态st,在i点时的最小花费,用三进制状压.以后任意进制 ...

  6. hdu 3001(三进制状压)

    题目 解法 看到这道题,我们就会想到旅行商问题.但是这里每一个点可以经过最多两次,所以我们用三进制表示就好了. 代码 #include <iostream> #include <cs ...

  7. HDU 3001 Travelling 3进制状压dp

    题意:10个点,若干条边,边有花费,每个点最多走两次,求走过所有点,花费最少 分析:因为每个点最多走两次,所以联想到3进制,然后枚举状态,就行了(我也是照着网上大神的代码写的) #include &l ...

  8. hdu 3001 三进制状压

    题意:tsp问题,但是每个点可以最多走两次 链接:点我 转移方程见代码 #include<iostream> #include<cstdio> #include<cstr ...

  9. [状压dp]HDU3001 Travelling

    题意: 走n个城市, m条路, 起点任意, 每个城市走不超过两次, 求最小花费, 不能走输出-1. $1\le n\le 10$ 分析: 每个城市的拜访次数为0 1 2, 所以三进制状压, 先预处理1 ...

随机推荐

  1. Dungeon Master(逃脱大师)-BFS

    Dungeon Master Description You are trapped in a 3D dungeon and need to find the quickest way out! Th ...

  2. Python知识点入门笔记——基本控制流程

    复合赋值语句 在Python中,可以使用一次赋值符号,给多个变量同时赋值:                  划重点:age_1,age_2 = age_2,age_1这种操作是Python独有的 i ...

  3. linux-最最最最最常用的操作

    去除两个文件中相同的内容 比如我想把file1中不含文件file2的内容保留下来:(这个在抠一些内容的时候挺好用的) awk '{print $0}' file1 file2 |sort|uniq - ...

  4. (WPF&Silverlight)silverlight自定义控件

    2个半小时弄懂了自定义控件是怎么回事儿. 在silverlight中创建一个UserControl,把上面sliderbar的外观和功能都封装在里面. 以自定义控件mapslider控件为例: 1.首 ...

  5. 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1469  Solved: ...

  6. loj2051 「HNOI2016」序列

    ref #include <algorithm> #include <iostream> #include <cstdio> #include <cmath& ...

  7. User Account Control

    User Account Control 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! User Account Control (UAC : 用户帐户控制)是微软为 ...

  8. NodeJs初学者经典入门解析

    Node.js 是一个基于谷歌浏览器JavaScript执行环境建立的一个平台,让JavaScript可以脱离客户端浏览器运行,让 JavaScript具有服务器语言的能力.我们可以使用NodeJs方 ...

  9. Python+Selenium练习篇之14-获取当前页面的title

    前面文章介绍了如何获取当前页面的URL的值,本文介绍如何获取当前页面的title,这个也可以作为测试结果的依据,通过得到的title和预期的值对比,可以支持我们判断页面跳转正确. 相关脚本代码如下: ...

  10. Leetcode 507.完美数

    完美数 对于一个 正整数,如果它和除了它自身以外的所有正因子之和相等,我们称它为"完美数". 给定一个 正整数 n, 如果他是完美数,返回 True,否则返回 False 示例: ...