注意有重边
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
int map[11][11];
int N, M;
int dp[11][59049];
int statu[12][59049];
int moves[12] = { 0, 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049 };
int main(){
memset( statu, 0, sizeof( statu ) );
for( int i = 0; i < 59049; i++ ){
int t = i, j = 1;
while( t != 0 ){
statu[j++][i] = t % 3;
t /= 3;
}
}
while( scanf( "%d%d", &N, &M ) != EOF ){
memset( dp, -1, sizeof( dp ) );
memset( map, -1, sizeof( map ) );
for( int i = 0; i < M; i++ ){
int temp1, temp2, temp3;
scanf( "%d%d%d", &temp1, &temp2, &temp3 );
if( map[temp1][temp2] == -1 ){
map[temp1][temp2] = temp3;
map[temp2][temp1] = temp3;
}else{
map[temp1][temp2] = map[temp2][temp1] = min( map[temp1][temp2], temp3 );
}
}
for( int i = 1; i <= N; i++ ){
dp[i][moves[i]] = 0;
}
int ans = MAX;
for( int i = 1; i < moves[N+1]; i++ ){
int flag = true;
for( int j = 1; j <= N; j++ ){
if( statu[j][i] == 0 ){
flag = false;
}
if( dp[j][i] == -1 ){
continue;
}
for( int k = 1; k <= N; k++ ){
if( k == j ){
continue;
}
if( statu[k][i] >= 2 ){
continue;
}
if( map[j][k] == -1 ){
continue;
}
if( dp[k][i+moves[k]] == -1 || dp[k][i+moves[k]] > dp[j][i] + map[j][k] ){
dp[k][i+moves[k]] = dp[j][i] + map[j][k];
}
}
}
if( flag ){
for( int j = 1; j <= N; j++ ){
if( dp[j][i] == -1 ){
continue;
}
ans = min( ans, dp[j][i] );
}
}
}
if( ans == MAX ){
cout << -1 << endl;
}else{
cout << ans << endl;
}
}
return 0;
}