本来是在light上看到的这题的。。。然后一直不过,没想到在poj上能过。。。。。。呵呵
题目是说每条边至少走一次然后回到原点,那么找出所有奇数度的节点两两相连得到欧拉路
AC代码如下:
#include
#include
#include
#include
#include
using namespace std;
#define MAX 0x3f3f3f3f
int minlength[16][16], weight[16][16];
int N, M, ans;
int deg[16];
int odddeg[16], tot;
int dp[1<<15];
int main(){
int T, Case = 1;
// cin >> T;
while( cin >> N && N ){
cin >> M;
memset( deg, 0, sizeof( deg ) );
memset( weight, 0x3f, sizeof( weight ) );
for( int i = 1; i <= N; i++ ) weight[i][i] = 0;
ans = 0;
for( int i = 1; i <= M; i++ ){
int temp1, temp2, temp3;
cin >> temp1 >> temp2 >> temp3;
ans += temp3;
weight[temp2][temp1] = min( temp3, weight[temp2][temp1] );
weight[temp1][temp2] = weight[temp2][temp1];
deg[temp1]++;
deg[temp2]++;
}
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
minlength[i][j] = weight[i][j];
}
}
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
for( int k = 1; k <= N; k++ ){
minlength[i][j] = min( minlength[i][j], minlength[i][k] + minlength[k][j] );
}
}
}
tot = 0;
for( int i = 1; i <= N; i++ ){
if( deg[i] % 2 ){
odddeg[tot++] = i;
}
}
memset( dp, 0x3f, sizeof( dp ) );
dp[0] = 0;
for( int stu = 0; stu < ( 1 << tot ); stu++ ){
for( int i = 0; i < tot; i++ )if( !( stu & ( 1 << i ) ) ){
for( int j = 0; j < tot; j++ )if( !( stu & ( 1 << j ) ) && i != j ){
dp[stu|(1<