题目链接 :https://acm.hdu.edu.cn/showproblem.php?pid=3001

题目大意:一个人从任意点出发访问所有城市,并且每个城市访问的次数不超过2次,问最少的花费是多少,如果到达不了,输出 -1。

详细看代码注释,已经在代码里注释的很清楚了

#include<bits/stdc++.h>
using namespace std;#define ll long long
#define sc(x) scanf("%d",&x)
#define _sc(x) scanf("%lld",&x)
#define pf(x) printf("%d",x);
#define _pf(x) printf("%lld",x);
#define FOR(i,a,b) for(int i = a;i<=b;++i)
#define _FOR(i,a,b) for(int i = a;i<b;++i)const ll mod = 1e9+7;
const ll maxn = 1e6+10;
const double eps = 1e-6;
const int INF = INT_MAX;ll pow2(ll a,ll n){ ll res = 1ll;while(n){if(n&1) res = (res*a)%mod;a = (a*a)%mod;n >>= 1;}return res;}ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; }int T;
int n,m;
int g[15][15];
int dp[15][60000];
int in[15],bit[60000][15];
void init(){in[0] = in[1] = 1;/* 初始化每个城市作为起点的状态 , 即 1 , 10 , 100 , 1000 (注意: 三进制下)例如 , 三进制下的 1 十进制下是 1 , 代表第一个城市三进制下的 10 十进制下是 3 , 代表第二个城市 三进制下的 100 十进制下是 9 , 代表第三个城市因为每个城市都有三种状态 (0,1,2) , 城市1,2,3 三进制表示下 相当于 3的 0次幂,3的 1次幂,3 的二次幂 */ FOR(i,2,12){in[i] = in[i-1] * 3;}/*枚举所有状态,对于每个状态 k , 查询状态下每一位的状态值(0,1,2) */ _FOR(k,1,in[11]){int temp = k;FOR(i,1,10){bit[k][i] = temp % 3;temp /= 3;}}
}bool check(int state){/* 检查每个状态的所有城市位置必须不等于 0 */ /*等于 0 代表没访问过等于 1 代表访问过一次等于 2 代表访问郭两次 */ FOR(i,1,n){if(!bit[state][i]) return false;}return true;
}void solve(){memset(g,127,sizeof(g));memset(dp,127,sizeof(dp));FOR(i,1,m){int u,v,w;cin >> u >> v >> w;// 防止重边 , 遇到重边取最小代价 w g[u][v] = g[v][u] = min(g[u][v],w);}/*dp[i][j] 目前到达第 i 个点的时候状态是 j的最小代价是dp[i][j] */FOR(i,1,n){/* 初始化 , 从每个点出发的代价为 0 *//* 从第 i 个点 出发的状态是 in[i] , 最小代价是 0 */ dp[i][in[i]] = 0;}_FOR(k,0,in[n+1]){/* 遍历所有子集 , 因为有三种状态(没走,走一次,走两次),因此对应 3的 n 次幂 */FOR(i,1,n){ /* 枚举每个城市点作为起始点 *//*到达第 i 个点的状态 k 的最小代价如果大于 (1 << 30)说明还没到达这个点,状态 k 不存在 (因为初始化为一个比 (1 << 30) 还要大的数 )比 (1 << 30) 大即不存在到达这个点的 k 状态最小代价 */if(dp[i][k] >= (1 << 30)) continue;/* 遍历相邻点 */FOR(j,1,n){/* 如果此状态下的第 j 位(第 j 个城市) 大于 1 证明已经走了两次不能再走了 或者 城市 i 到 城市 j 没有边到达也不能走 */ if(bit[k][j] > 1 || g[i][j] >= (1 << 30)) continue;/*转移方程 dp[j][k+in[j]] = min(dp[j][k+in[j]],dp[i][k] + g[i][j]); dp[j][k + in[j]] : 到达第 j 个点状态为 k+in[j] 的最小代价,此时的 k 是 到达 i 时的状态,所以得加上访问 j的状态 ----> in[j] , 相当于状态 k 的第 j 位 加上 1 ,代表访问过一次 j 城市 dp[i][k] + g[i][j] : 到达第 i 个点状态为 k 的最小代价 + 从i城市到j城市的代价 (i,j) 到达 第 i 个城市状态为 k 的最小代价 + g[i][j] 表示 加上从第 i 个城市到达第 j 个城市所需的代价 */ /*注意:这个dp方程是更新到达 第 j 个城市状态为 k + in[j] 的最小代价 , 不是更新 dp[i][k]*/ dp[j][k+in[j]] = min(dp[j][k+in[j]],dp[i][k] + g[i][j]); }} }int ans = (1 << 30);_FOR(k,1,in[n+1]){/* 遍历每一种状态 */if(check(k)){/* 如果该状态满足题目要求 */FOR(i,1,n){/* 找到从哪个城市作为结尾的最小代价 */ans = min(ans,dp[i][k]);}} }cout << (ans == (1 << 30) ? -1 : ans) << "\n";
}
int main(void){init();T = 1;while(scanf("%d %d",&n,&m) == 2){solve();}return 0;
} 

Travelling HDU-3001相关推荐

  1. HDU 3001 三进制状压DP

    HDU 3001 三进制状压DP N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方 ...

  2. HDU 3001 Travelling

    http://acm.hdu.edu.cn/showproblem.php?pid=3001      题意:小明想去n个城市游玩,m条路,从一个城市到达另一个城市有一定的花费,每个城市最多可以走两次 ...

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

    题意 n(n<=10)n(n个城市,知道每个城市间的旅行费用,但每个城市最多走两遍.问最小花费是多少 . 也就是每个城市可以走两次的tsp问题. 分析 最多走两次,三进制0 1 2可满足,即用三 ...

  4. hdu 3001 tsp问题/三进制

    题意:变形tsp 必须搞成三进制 #include <bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a; ...

  5. 搜索专题(不定期更新)

    1.POJ 2386  Lake Counting 题意:给出一块区域,询问有多少个湖泊? 思路:DFS,对于'W',深搜一次,并标记已访问.之后每次对未访问的'W'做一次深搜. 1 #include ...

  6. kuangbin带你飞专题合集

    题目列表 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题二 搜索进阶 [kuangbin带你飞]专题三 Dancing Links [kuangbin带你飞]专题四 最短路 ...

  7. 算法学习经典例题整理

    陆续会对本篇博客进行更新! 搜索:https://vjudge.net/contest/292597 区间DP:https://vjudge.net/contest/293892 树状背包:https ...

  8. [置顶] 状态压缩DP 简单入门题 11题

    1.每一行用一个二进制数表示, 有些二进制数是题目中不合法的状态,我们可以预处理出一行合法状态的个数,在递推的过程中复杂度就会大大降低. POJ 3254        Corn Fields     ...

  9. kuangbin带你飞 专题1-23 题单

    kuangbin大神,对于打过ACM比赛的ACMer,无人不知无人不晓. 在此,附上vjudge平台上一位大神整理的[kuangbin带你飞]专题目录链接. [kuangbin带你飞专题目录1-23] ...

  10. 老鱼的-kuangbin专题题解

    kuangbin专题问题一览 专题一 简单搜索 POJ 1321 棋盘问题 POJ 2251 Dungeon Master POJ 3278 Catch That Cow POJ 3279 Flipt ...

最新文章

  1. 业余时间用哪里,哪里就有发展的可能
  2. Reading-又更新了一些内容【Kotlin+MVP+Retrofit】
  3. python多线程爬虫实例-Python爬虫开发【第1篇】【多线程爬虫及案例】
  4. linux I/O--IO原理和几种零拷贝机制(五)
  5. vmware, failed to lock the file 的解决
  6. xmpp muc 群聊协议 3
  7. Atmel与ARM合力打造物联网开发平台
  8. [fastjson] - fastjson中 JSONObject 和 JSONArray
  9. 生命的书写,梦想的呈现
  10. Script to show Active Distributed Transactions
  11. 【渝粤教育】国家开放大学2018年秋季 0716-21T工程建设法规 参考试题
  12. python 词表里的词不符合_【NLP】词表太大怎么办—Adaptive softmax模型和代码解析...
  13. PS、PR、AE、AI、AU区别
  14. 华为AI Gallery社区《基于机器学习的欧洲杯赛事预测》技术分析系列——(一)基本原理
  15. WinSxS目录下文件的清除
  16. Python读文件的三种方法对比
  17. Web安全(任意文件下载)
  18. LAMP服务器环境搭建及工程部署
  19. 180724 安卓-SSLPinning及反制
  20. 0xc000007b应用程序无法正常启动解决方案(亲测有效)

热门文章

  1. 30+ 个工作中常用到的前端小知识
  2. SM3国密杂凑值算法的原理和c语言实现
  3. CSS3 3D 球体自转特效
  4. 程序员业余时间副业技术变现赚钱的10个私藏方法,悄悄告诉你!
  5. 碱性提镓树脂,贵重金属镓的深度去除和回收
  6. oracle增加字段为主键自增_oracle 自增序列实现 可作为主键
  7. 【Numpy】reshape函数
  8. 以太坊正成为人类到达谢林点的高效方式?
  9. 这 12 张手绘图,让我彻底搞懂了微服务架构!
  10. C语言如何让图形的眼睛动起来,C语言图形编程--俄罗斯方块制作(一)详解