题目
思路&&题解:
其实根本不会做。。。
自己的思路:
可以考虑用状压dp,发现我的dp是5维的,直接自闭
正解:dfs状压dp
可以考虑搜索,首先先确定根,然后还是用状压的思想,记一下每一个点的深度,然后直接暴力转移即可
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 13;
ll dis[MAXN] , dp[1<<MAXN];
int n , m , G[MAXN][MAXN];
void dfs( int now ){
for( int i = 1 ; i <= n ; i ++ ){
if( ( now & ( 1 << i -1 ) ) ){
for( int j = 1 ; j <= n ; j ++ ){
if( now & ( 1 << j - 1 ) || G[i][j] == 0x3f3f3f3f ) continue;
if( dp[now|(1<<j-1)] > dp[now] + 1ll * ( dis[i] + 1 ) * G[i][j] ){
dp[now|(1<<j-1)] = dp[now] + 1ll * ( dis[i] + 1 ) * G[i][j];
dis[j] = dis[i] + 1;
dfs( now | ( 1 << j - 1 ) );
}
}
}
}
}
int main(){
scanf( "%d%d" , &n , &m );
for( int i = 1 ; i <= n ; i ++ )
for( int j = 1 ; j <= n ; j ++ ) G[i][j] = 0x3f3f3f3f;
for( int i = 1 ; i <= m ; i ++ ){
int x , y , z;scanf( "%d%d%d" , &x , &y , &z );
G[x][y] = G[y][x] = min( G[x][y] , z );
}
//memset( dp , 0x7f, sizeof( dp ) );
ll ans = 0x7f7f7f7f;
for( int i = 1 ; i <= n ; i ++ ){
memset( dp , 0x7f , sizeof( dp ) );
for( int j = 1 ; j <= n ; j ++ ) dis[j] =0 ;
dp[1<<(i-1)] = 0;dis[i] =0 ;
dfs( 1<<(i-1) );
ans = min( ans , dp[(1<<n)-1] );
}
printf( "%lld" , ans );
return 0;
}
至于为什么不会超时,就要分析时间复杂度了:考虑每一个状态到底会被算多少次,也就是只会由n个状态转移来,做了n次,所以时间复杂度是的