hdu3001——Travelling 三进制TSP, 状态压缩

Travelling

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

Total Submission(s): 4106    Accepted Submission(s): 1310

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

2009 Multi-University Training Contest 11 - Host by HRBEU

Recommend

gaojie   |   We have carefully selected several similar problems for you:  3004 3002 3006 3007 3003

这题一看就是TSP,然后想到要状压,但是这里每个城市最多可以走两次,所以不能用普通的二进制来状压,需要三进制

三进制每一位是0 1 2, 0表示这座城市没到过,1表示到过一次,2表示到过两次

由于一共10座城市,我们先把3^0 --- 3 ^ 10预处理出来,然后化作三进制存好,接着就是dp,但是要注意,可以作为最后状态的状态,它的每一位都不为0(否则就有某个城市没到过),最后枚举所有可以作为尾状态的状态然后求个最小值就ok了

#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int inf = 0x3f3f3f3f;

int dp[60000][15];
int dist[15][15];
int three[15] = {0, 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049};
int city[60000][15];

int main()
{
	int n, m, u, v, w;
	memset (city, inf, sizeof(city));
	for (int i = 0; i < 59059; ++i)
	{
		int tmp = i;
		for (int j = 1; j <= 10; ++j)
		{
			city[i][j] = tmp % 3;
			tmp /= 3;
		}
	}
	while (~scanf("%d%d", &n, &m))
	{
		memset (dist, inf, sizeof(dist));
		memset (dp, inf, sizeof(dp));
		for (int i = 1; i <= n; ++i)
		{
			dp[three[i]][i] = 0;
		}
		dp[0][0] = 0;
		for (int i = 1; i <= m; ++i)
		{
			scanf("%d%d%d", &u, &v, &w);
			dist[u][v] = min(dist[u][v], w);
			dist[v][u] = dist[u][v];
		}
		int ans = inf;
		for (int i = 0; i < three[n + 1]; ++i)
		{
			bool is_end = 1;
			for (int j = 1; j <= n; ++j)
			{
				if (city[i][j] == 0)
				{
					is_end = 0;
				}
				for (int k = 1; k <= 10; ++k)
				{
					if (city[i][j] == 2)
					{
						continue;
					}
					dp[i + three[j]][j] = min(dp[i + three[j]][j], dp[i][k] + dist[k][j]);
				}
			}
			if (is_end)
			{
				for (int j = 1; j <= n; ++j)
				{
					ans = min(ans, dp[i][j]);
				}
			}
		}
		if (ans == inf)
		{
			printf("-1\n");
			continue;
		}
		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-10-11 06:40:10

hdu3001——Travelling 三进制TSP, 状态压缩的相关文章

Travelling (三进制+状压dp)

题目链接 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline ll read(){ 5 int x=0,f=1;char ch=getchar(); 6 while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} 7 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch

TSP - 状态压缩dp

2017-08-11 21:10:21 艾教写的 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<set> #include<stack> using namespace std; typedef long long LL; int n

HDU 3001 Travelling(状态压缩DP+三进制)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目大意:有n个城市,m条路,每条路都有一定的花费,可以从任意城市出发,每个城市不能经过两次以上,要求经过所有城市并且花费最少,求出最小花费. 解题思路:三进制的状态压缩DP,跟二进制还是有一点不一样的,因为三进制没有直接的位运算,还要自己先做处理利用num[i][j]记录数字i各位的三进制表示方便计算,其他的就跟二进制状态压缩没有太大区别了.还有注意: ①开始要将n个起点初始化,dp[bit

状态压缩dp小结

最近一段时间算是学了一些状态压缩的题目,在这里做个小结吧 首先是炮兵布阵类题目,这类题目一开始给定一个矩形,要求在上面放置炮兵,如果在一格放了炮兵那么周围的某些格子就不能放炮兵,求最大能放置炮兵的数量 poj1185炮兵布阵 hdu2176 炮兵布阵修改版 poj3254 炮兵布阵弱化版 poj1565 方格取数 然后是状态集合类的题目,这类题目给定一个集合的元素,要求重排列以达到最大化收益,即从已知状态推出未知状态,通常需要处理出元素之间的两两对应关系 zoj3471 模板 poj2817 在

HDU 3001 Travelling (三进制状态压缩 DP)

题意:有 n 个city,可以选择任一城市作为起点,每个城市不能访问超过2次, 城市之间有权值,问访问全部n个城市需要的最小权值. 思路:因为每个城市可以访问最多两次,所以用三进制表示访问的状态. 详细见代码注释!!!! #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #inclu

hdu-3001 三进制状态压缩+dp

用dp来求最短路,虽然效率低,但是状态的概念方便解决最短路问题中的很多限制,也便于压缩以保存更多信息. 本题要求访问全图,且每个节点不能访问两次以上.所以用一个三进制数保存全图的访问状态(3^10,空间是足够的),用dp[z+bit[j]][j]=dp[z][i]+ct[i][j]就可以表示,从上一状态以i为结束点,转移到把j加入路径末端后的状态(感叹一下位运算的神奇). // // main.cpp // hdu_3001 // // Created by Luke on 2016/11/12

hdu 3001 Travelling(状态压缩 三进制)

Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6600    Accepted Submission(s): 2144 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is

hdu3001 (三进制状态压缩 dp)

src: http://acm.hdu.edu.cn/showproblem.php?pid=3001 思路:每个顶点经过最多2次,也就是有0 1 2三种状态!用bit[]存三进制下各位的值(这样dp的状态概念就可以解决最短路问题的许多限制,通过压缩可以保存更多的值~),dp[z][j]表示z状态下,以j为终点的路径费用!!! 待更~~~ 原文地址:https://www.cnblogs.com/WindFreedom/p/8763093.html

hdu3001Travelling (状态压缩DP,三进制)

Travelling Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3611 Accepted Submission(s): 1132 Problem Description After coding so many days,Mr Acmer wants to have a good rest.So travelling is the b