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

Travelling

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8286    Accepted Submission(s): 2703

Problem Description
After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because superman can bring him to any city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So he turns to you for help.
 
Input
There are several test cases,the first line is two intergers n(1<=n<=10) and m,which means he needs to visit n cities and there are m roads he can choose,then m lines follow,each line will include three intergers a,b and c(1<=a,b<=n),means there is a road between a and b and the cost is of course c.Input to the End Of File.
 
Output
Output the minimum fee that he should pay,or -1 if he can't find such a route.
 
Sample Input
2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10
 
Sample Output
100
90
7
 
Source
 
 
 
 
题解:
1.对于每一个点, 有三种状态:没有被访问、被访问一次、被访问两次。所以需要用三进制进行压缩。
2.dp[status][last]表示:在状态为status下(即走了多少个点,以及每个点走了多少次),最后走的是last点的最小花费。
3.对于一个已有状态:dp[s][j],枚举每一个点k,如果这个点k不是j,而k、j有边,且k被访问的次数不超过2次,那么下一步就可以访问k点。
4.类似的题目:HDU4856
 
 
代码如下:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
#define ms(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = +; int n, m;
int g[MAXN][MAXN], c[MAXN], dp[][]; int main()
{
c[] = ;
for(int i = ; i<=; i++) //计算三进制
c[i] = c[i-]*; while(scanf("%d%d", &n, &m)!=EOF)
{
memset(g, -, sizeof(g));
for(int i = ; i<=m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
u--; v--;
if(g[u][v]!=-) w = min(w, g[u][v]);
g[u][v] = g[v][u] = w;
} memset(dp, -, sizeof(dp));
for(int i = ; i<n; i++)
dp[c[i]][i] = ; int ans = INF;
for(int s = ; s<c[n]; s++)
for(int j = ; j<n; j++)
{
if(dp[s][j]==-) continue; //此状态不存在, 跳过 int cnt = ;
for(int k = ; k<n; k++)
{
if(j!=k && g[j][k]!=- && (s/c[k])%< )
{
int tmp = s + c[k]; //递推出下一个状态
if(dp[tmp][k]==- || dp[tmp][k]>dp[s][j]+g[j][k]) //更新
dp[tmp][k] = dp[s][j] + g[j][k];
} if((s/c[k])%) cnt++; //统计状态s下走了多少个点
} if(cnt==n) ans = min(ans, dp[s][j]); //如果状态s下走完所有点, 则更新答案
}
printf("%d\n", ans==INF?-:ans);
}
}

HDU3001 Travelling —— 状压DP(三进制)的更多相关文章

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

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

  2. Travelling(HDU3001+状压dp+三进制+最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目: 题意:n个城市,m条边,每条边都有一个权值,问你经过所有的城市且每条边通过次数不超过两次 ...

  3. HDU3001 Traveling (状压dp+三进制+Tsp问题总结)

    (1)这道题最多可以走两次,所以有0, 1, 2三种状态,所以我们要用三进制 如果要用三进制,就要自己初始化两个数组, 一个是3的n次方,一个是三进制数的第几位的数字是什么 void init() { ...

  4. HDU3001 Travelling 状压DP

    哭瞎啊,每一个城市能够经过至多两次,但没有要求必须经过两次.想用 两个状压来乱搞搞.结果自觉得会T.结果 WA了,搞了一下午.没想到用三进制啊.智商捉急,參考了 http://blog.csdn.ne ...

  5. HDU 3001 Travelling ——状压DP

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

  6. hdu3001(状压dp,三进制)

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

  7. hdu3001(状压dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意:n 个城市已经 m 条路 以及对应路费 c,要求遍历所有城市最少的路费,每个城市不能超过2 ...

  8. HDU 3001 Travelling (状压DP + BFS)

    题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次.现在给出城市之间的来往路费,他可以选择任意一个点为起点. 问逛遍所有城市的最低路费是多少. 析:用三进制表示每个城市的访问 ...

  9. hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...

随机推荐

  1. .NET中的缓存实现

    软件开发中最常用的模式之一是缓存,这是一个简单但非常有效的概念,想法是重用操作结果,执行繁重的操作时,我们会将结果保存在缓存容器中,下次我们需要该结果时,我们将从缓存容器中取出它,而不是再次执行繁重的 ...

  2. [luoguP2622] 关灯问题II(状压最短路)

    传送门 本以为是状压DP,但是有后效性. 所以写一手状压spfa #include <queue> #include <cstdio> #include <cstring ...

  3. BZOJ4551 - [TJOI2016]树

    Portal Description 给出一棵\(n(n\leq10^5)\)个点的以\(1\)为根的有根树,进行\(Q(Q\leq10^5)\)次操作: 标记一个点\(x\). 询问\(x\)的祖先 ...

  4. 最大和(codevs 1648)

    题目描述 Description N个数围成一圈,要求从中选择若干个连续的数(注意每个数最多只能选一次)加起来,问能形成的最大的和. 输入描述 Input Description 第一行输入N,表示数 ...

  5. 金明的预算方案(codevs 1155)

    题目描述 Description 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只 ...

  6. as3 二维数组的定义

    大家都知道as3里面是不能直接定义多维数组 所以不能直接用arr[2][3]这样的方法来获取数组里面的值.如何才能创立多维数组了? 方法如下先定义一个数组 var MapData:Array=new ...

  7. P1420 最长连号

    洛谷——P1420 最长连号 题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入输出格式 输入格式: 第一行,一个数n; 第 ...

  8. Permutations(排列问题,DFS回溯)

    Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...

  9. jquery 关于ajax 及其son

    <%@ page language="java" pageEncoding="UTF-8"%><%@include file="/c ...

  10. Nexus搭建Maven私有仓库

    原文:http://blog.csdn.net/rickyit/article/details/54927101 前言 Nexus Repository Manager is a Javaapplic ...