里面包含了很多内容的一道题 可以学到很多
题意 很简单 就是一个人 要绕城市一圈 不必回到起点 但是每个城市都要经过 并且最多每个重复走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