hdu--3001--类似旅行商<tsp>

里面包含了很多内容的一道题 可以学到很多

题意 很简单 就是一个人 要绕城市一圈 不必回到起点 但是每个城市都要经过 并且最多每个重复走2次

注意 城市数量是 <=10的  如果 你以前就遇到过 类似的题 肯定能很快反应过来 状压dp 在某一维开个3维数组 0 1 2分别城市在该状态下经过某城市的次数为多少

所以 就是个 三进制的压缩  蛮好的 以前只听过二进制 我孤陋寡闻了 =_=

dp转移方程很简单 主要是 枚举状态的时候 各种细节要注意

dp[ state+three[j] ][j] = min( dp[ state+three[j] ][j] , dp[ state ][i] + mp[i][j] );

因为 城市个数实在是太水了 就用最简单的 二维矩阵存储吧 但会有重边 需要更新取最小值

for( int i = 0 ; i<n ; i++ )
{
    dp[ three[i] ][i] = 0;
}

这是个很重要的初始化 因为 我们没有固定从哪个点出发 那就表示 任意一点都可以当做起点

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5
 6 int n;
 7 const int inf = 0X3f3f3f;
 8 const int v = 60000;
 9 const int size = 11;
10 int dp[v][size] , vis[v][size];
11 int mp[size][size];
12 int three[size];
13
14 void init( )
15 {
16     int num;
17     three[0] = 1;
18     for( int i = 1 ; i<size ; i++ )
19     {
20         three[i] = three[i-1] * 3;
21     }
22     for( int i = 1 ; i<three[size-1] ; i++ )
23     {
24         num = i;
25         for( int j = 0 ; j<size-1 ; j++ )
26         {
27             vis[i][j] = num % 3;
28             num /= 3;
29         }
30     }
31 }
32
33 int solve( )
34 {
35     bool flag;
36     int ans = inf;
37     for( int state = 1 ; state<three[n] ; state++ )
38     {
39         flag = true;
40         for( int i = 0 ; i<=n-1 ; i++ )
41         {
42             if( !vis[state][i] )
43                 flag = false;
44             if( dp[state][i] == inf )
45                 continue;
46             for( int j = 0 ; j<=n-1 ; j++ )
47             {
48                 if( i==j || mp[i][j] == inf || vis[state][j]>=2 )
49                     continue;
50                 dp[ state+three[j] ][j] = min( dp[ state+three[j] ][j] , dp[ state ][i] + mp[i][j] );
51             }
52         }
53         if( flag )
54         {
55             for( int i = 0 ; i<=n-1 ; i++ )
56             {
57                 ans = min( ans , dp[state][i] );
58             }
59         }
60     }
61     return ans;
62 }
63
64 int main()
65 {
66     cin.sync_with_stdio(false);
67     int m , a , b , c;
68     int ans;
69     init( );
70     while( cin >> n >> m )
71     {
72         memset( dp , inf , sizeof(dp) );
73         memset( mp , inf , sizeof(mp) );
74         for( int i = 0 ; i<n ; i++ )
75         {
76             dp[ three[i] ][i] = 0;
77         }
78         while( m-- )
79         {
80             cin >> a >> b >> c;
81             -- a;
82             -- b;
83             mp[a][b] = mp[b][a] = min( mp[a][b] , c );
84         }
85         ans = solve( );
86         if( ans == inf )
87             cout << -1 << endl;
88         else
89             cout << ans << endl;
90     }
91     return 0;
92 }

today:

  忍受某段时光

  然后会被自己感动

时间: 2024-10-06 05:06:15

hdu--3001--类似旅行商<tsp>的相关文章

遗传算法的简单应用-巡回旅行商(TSP)问题的求解

上篇我们用遗传算法求解了方程,其中用到的编码方式是二进制的编码,实现起来相对简单很多, 就连交配和变异等操作也是比较简单,但是对于TSP问题,就稍微复杂一点,需要有一定的策略, 才能较好的实现. 这次的TSP问题的题目是: 随机产生10~30个城市,每个城市之间的距离也是随机产生,距离的范围是[1,50],求最优的路径 ========================================================== 下面就是具体的求解,由于我的策略是基于知网上的<一种改进的遗

Hamilton回路 旅行商TSP问题 /// dp oj1964

题目大意: 给出一个n个顶点的无向图,请寻找一条从顶点0出发,遍历其余顶点一次且仅一次.最后回到顶点0的回路--即Hamilton回路. Input 多测试用例.每个测试用例: 第一行,两个正整数 n 和 e ,0 < n ≤ 21 ,n < e < n×n/2 ,表示该无向图的顶点个数,以及边的数量.顶点编号是0-n-1 第二行至e+1行,每行3个非负整数 u , v 和 w ,分别表示顶点u与顶点v之间有一条边,其权值为w . Output 如果存在多条Hamilton回路,请输出长

ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TshingHua OJ-旅行商TSP)

做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(TSP) Description Shrek is a postman working in the mountain, whose routine work is sending mail to n villages. Unfortunately, road between villages is

hdu 3001 Travelling TSP变形 三进制状压dp

// hdu 3001 TSP问题的变形 // 这次到每个点最多两次,所以可以用三进制的类推 // dp[S][u]表示当前在u点访问状态为S时所得到的最小的开销 // 采用刷表法,即用当前的状态推出它所能转移的状态 // dp[S][u] 可以到达的状态为dp[S+state[v]][v](dist[u][v]!=inf) // dp[S+state[v]][v] = max(dp[S+state[v]][v],dp[S][u]+dist[u][v]); // 其中每个点最多访问2次 // 技

hdoj 3001 Travelling 【3进制+旅行商】

题目:hdoj 3001 Travelling 题意:标准的旅行商加一句话,每个点最多走两次. 分析:状态转移方程一模一样,只是要三进制,因为每个点有三种状态 0 ,1 2 定义状态:dp[st][i] :在状态为 st 时 当前在 i 点的最小花费 转移方程:dp[now][j] = min(dp[now][j],dp[st][i]+mp[i][j]):now是st可以一次转移得到的状态 注意初始化. 分析: #include <cstdio> #include <algorithm&

美国13509个城镇的经纬度和TSP旅行商回路

美国13509个城镇的经纬度和TSP旅行商回路         在网上下载了美国美国13509个城镇的经纬度和TSP旅行商回路(下载网址:http://www.verysource.com/code/3731091_1/usa13509.opt.tour.html),按照网上的结果,13509个城市的回路结果是:19982859.         我认为,下面这个表里面标示的经纬度,第一个城镇经度为81.7827778,纬度为24.552.778:第二个城镇经度为81.0905556,纬度为24

TSP 旅行商

THUOJ 数据结构(上)TSP 旅行商 点击查看题目:TSP旅行商 实现思路 建立邻接表 每读入一条边u->v,将其插入u中(后面将实现的tspNode中的边,是以其为出发点的边),并将v的入度+1 拓扑排序过程中计算最长道路经过的村庄数 算法:零入度拓扑排序,p166 of 数据结构(c++语言版)_邓俊辉 扫描所有节点,入度为0的入栈 从栈顶开始,每读一个节点a,扫描其边,相连节点b入度-1,ind变为0的入栈: 更新b'路径长度=max(a's+1,b'):更新max路径: 边界情况处理

旅行商(n&lt;15)

http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=420 #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <stack> #include <queue> #include <vector> #include <ma

HDU 3001 状压DP

有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路  成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到任意的一个城市..然后他就在城市之间游荡.要满足他要游玩所有的城市..并且.每个城市最多去两次.要求路程最短..如果他不能游完所有的城市,,那么..就输出-1  否则 输出最短距离 如果用搜索...不靠谱  然后用搜索,, 怎么压缩?? 用一个整型数 i 表示他现在的状态..显然一个城市是要用两位..00