题目链接

题意

给定一个\(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. css3 横向拖拽

    css: .tab{         list-style-type: none;         display:-webkit-box;         display:-webkit-flex; ...

  2. jquery/js/a标签实现当前页面跳转的两种方法

    在逛购物网站首页时经常看到侧边导航栏,当我们点击导航栏中某一项时会跳转到当前页面的某一处 有两种方法实现,一种是利用js计算好各位置的高度,通过绑定事件使页面跳转到指定位置,另一种是利用a标签进行当前 ...

  3. python之格式化

    python有两种方式可以格式化一种是用%s,一种使用format(2.6)进入的,从下面的代码可以看出,效果差不多. name = 'edward' age = 27 print("My ...

  4. oracle for update和for update nowait 的区别

    原文地址:http://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html 1.for update 和 for update nowa ...

  5. 最小生成树:HDU1863-畅通工程

    畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  6. [洛谷P1168]中位数(Splay)/(主席树)

    Description 给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[2], -, A[2k - 1]的中位数.即前1,3,5,--个数的 ...

  7. VBA连接到SQL2008需要加上端口号

    VBA连接到SQL2008需要加上端口号1433,比如 conn = "server=XXXX.XXXX.XXXX.XXXX,1433;provider=SQLOLEDB.1;databas ...

  8. Java多线程-join方法

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. 具体例子看链接 ...

  9. IOS开发学习笔记018- 一般控件的使用

    1.移动 2.动画 3.缩放 3.旋转 4.简化代码 5.总结 UIButton 的两种状态 normal highlighted  1.移动 OC语法规定:不允许直接修改某个对象中结构体属性的成员. ...

  10. SQL 基础语法详解

    SQL 命令一般分为 DQL.DML.DDL DQL:数据查询语句,基本就是 SELECT 查询命令,用于数据查询 DML:Data Manipulation Language 的简称,即数据操纵语言 ...