题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次。现在给出城市之间的来往路费,他可以选择任意一个点为起点。

问逛遍所有城市的最低路费是多少。

析:用三进制表示每个城市的访问次数,然后 bfs 进行遍历,不过要注意这个题卡内存,必须要去年一些无用的状态,要不然会超内存的,还不能枚举每个城市,

这样可能会超时的,可以直接把所有的城市放进去,直接进行遍历。一个比较经典的题目。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e16;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 10 + 5;
const int mod = 100000000;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
} int G[10][10];
int dp[60000][10];
int f[10]; struct Node{
int state, pos;
Node(int s, int p) : state(s), pos(p) { }
}; int calc(int state, int i){
return state + f[i];
} bool judge(int state){
for(int i = 0; i < n; ++i, state /= 3)
if(state % 3 == 0) return false;
return true;
} int bfs(){
memset(dp, INF, sizeof dp);
queue<Node> q;
for(int i = 0; i < n; ++i){
dp[calc(0, i)][i] = 0;
q.push(Node(calc(0, i), i));
}
int ans = INF;
if(n == 1) return 0; while(!q.empty()){
Node u = q.front(); q.pop();
int state = u.state;
for(int i = 0; i < n; ++i) if(G[u.pos][i] != INF){
if(state / f[i] % 3 == 2) continue;
int newstate = calc(state, i);
int neww = dp[state][u.pos] + G[u.pos][i];
if(dp[newstate][i] <= neww) continue; //去年无用的状态,要不然可能会超时或者超内存
dp[newstate][i] = neww;
if(judge(newstate)){
ans = min(ans, dp[newstate][i]);
continue;
}
else q.push(Node(newstate, i));
}
}
return ans;
} int main(){
f[0] = 1;
for(int i = 1; i < 10; ++i) f[i] = f[i-1] * 3;
while(scanf("%d %d", &n, &m) == 2){
memset(G, INF, sizeof G);
for(int i = 0; i < m; ++i){
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
--a, --b;
G[a][b] = G[b][a] = min(G[a][b], c);
}
int ans = bfs();
printf("%d\n", ans == INF ? -1 : ans);
}
return 0;
}

  

HDU 3001 Travelling (状压DP + BFS)的更多相关文章

  1. HDU 3001 Travelling ——状压DP

    [题目分析] 赤裸裸的状压DP. 每个点可以经过两次,问经过所有点的最短路径. 然后写了一发四进制(真是好写) 然后就MLE了. 懒得写hash了. 改成三进制,顺利A掉,时间垫底. [代码] #in ...

  2. HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二

    终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...

  3. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  4. BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS

    BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS Description Farmer John has taken the cows to a va ...

  5. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  6. HDU 3681 Prison Break(状压DP + BFS)题解

    题意:一张图,F是起点,Y是必须要到的点,D不能走,G可以充电.可以往四个方向走,每走一步花费一个电,走到G可以选择充满电或者不充,每个G只能充一次.问你走遍Y的最小初始点亮.number(G) + ...

  7. HDU 4284Travel(状压DP)

    HDU 4284    Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...

  8. HDU 4336 容斥原理 || 状压DP

    状压DP :F(S)=Sum*F(S)+p(x1)*F(S^(1<<x1))+p(x2)*F(S^(1<<x2))...+1; F(S)表示取状态为S的牌的期望次数,Sum表示 ...

  9. HDU3001 Travelling —— 状压DP(三进制)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3001 Travelling Time Limit: 6000/3000 MS (Java/ ...

随机推荐

  1. RequireJS 也可以引入 VUE

    RequireJS 也可以引入 VUE 由于 FastAdmin 是使用 RequireJS 导入 JS 模块的. 有人想把 VUE 也引入进去,虽然说也是可以,VUE 还是推荐使用 Webpack ...

  2. 试用 Eagle 9.1

    试用 Eagle 9.1 有推挤功能 原理图可以设置组装变体. 输出的 CAM 可以自定义,没有 Protel 那么死板. 保存的文件是 xml 文件,可以自由解析.

  3. 推荐几本学习MySQL的好书

    转载:http://mingxinglai.com/cn/2015/12/material-of-mysql/ 我这里推荐几本MySQL的好书,应该能够有效避免学习MySQL的弯路,并且达到一个不错的 ...

  4. Common 通用类库

    /// <summary> /// 传入虚拟路径 返回全路径的html字符串 /// </summary> /// <param name="context&q ...

  5. hihoCoder#1079(线段树+坐标离散化)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学 ...

  6. 机器学习:集成学习(集成学习思想、scikit-learn 中的集成分类器)

    一.集成学习的思想 集成学习的思路:一个问题(如分类问题),让多种算法参与预测(如下图中的算法都可以解决分类问题),在多个预测结果中,选择出现最多的预测类别做为该样本的最终预测类别: 生活中的集成思维 ...

  7. 【转】 Pro Android学习笔记(八四):了解Package(3):包间数据共享

    目录(?)[-] 共享User ID的设置 共享资源例子 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowing ...

  8. Servlet3.0之八:基于Servlet3.0的文件上传@MultipartConfig

    在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件,在Servlet3.0中提供了对文件上传的原生支持,我们不 ...

  9. Oracle 存储过程学习笔记

    1.存储过程简单实例 CREATE OR REPLACE PROCEDURE 存储过程名称 (参数in,参数out) AS -- 变量声明,每个声明用分号结束.可以在声明的同时初始化 name ); ...

  10. Linux 内核 UFO-非UFO 路径切换内存破坏漏洞的 PoC(CVE-2017-1000112)

    // A proof-of-concept local root exploit for CVE-2017-1000112. // Includes KASLR and SMEP bypasses. ...