题意 经过任意一条边最多两次 遍历所有节点
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> #define inf 0x1f1f1f1f using namespace std; int N,M,map[11][11],arr[32]; int hash[12] = {0,1,3,9,27,81,243,729,2187,6561,19683,59049}; int dp[177777][11]; void work( int num ) { int k = 1; memset( arr,0,sizeof(arr) ); while( num ) { arr[k++] = num%3; num /= 3; } } int main( ) { int i,j,k,t,u,v,val,res; while( scanf("%d%d",&N,&M) != EOF ) { memset( map,inf,sizeof(map) ); for( i = 1; i <= M; i++ ) { scanf("%d%d%d",&u,&v,&val); if( val < map[u][v] )map[u][v] = map[v][u] = val; } memset( dp,inf,sizeof(dp) ); for( i = 1; i <= N; i++ ) dp[hash[i]][i] = 0; res = inf; for( i = 1; i < hash[N+1]; i++ ) { int vis_all = 1;work(i); for( j = 1; j <= N; j++ ) { if( arr[j] == 0 )vis_all = 0; if( dp[i][j] == inf ) continue; for( k = 1; k <= N; k++ ) { if( j == k ) continue; if( map[j][k] == inf )continue; if( arr[k] >= 2 ) continue; int stu = i + hash[k]; dp[stu][k] = min( dp[stu][k],dp[i][j] + map[j][k] ); } } if( vis_all ) for( j = 1; j <= N; j++ ) res = min( res, dp[i][j] ); } if( res != inf ) printf("%d\n",res); else printf("-1\n"); } return 0; }