直接上代码,以后再补思路和注释
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
const int inf = 999999999;
int matrix[N][N],mapp[N][N];
int p[N][N];
int path[N],d[N];
int sg[N];
int cont[N];
int vis[N];
int n,m;
int top;
struct node{
int v,u,cost;
}gg[N];
void dfs(int beg){
for(int i=1;i<=n;i++){
if(matrix[beg][i]){
matrix[beg][i]--;
matrix[i][beg]--;
dfs(i);
}
}
path[top++]=beg;
}
void fleury(int beg){
/*
for(int i=1;i<=7;i++){
for(int j=1;j<=7;j++){
printf("%d ",matrix[i][j]);
}
puts("");
}
*/
top=0;
dfs(beg);
}
void floyed(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
//if(i==j||j==k||i==k) continue;
if(mapp[i][j]>mapp[i][k]+mapp[k][j]){
p[i][j]=k;
mapp[i][j]=mapp[i][k]+mapp[k][j];
}
}
}
}
}
void add(int i,int j){
int k;
k=p[i][j];
if(k==0) return;
add(i,k);
matrix[i][k]++;
matrix[k][i]++;
add(k,j);
//matrix[]
}
/*
int fuck(){
int i,j,k,maxx=inf;
for(i=1;i<=n;i++){
if(!g[i]) break;
}
if(i==n+1) return 0;
g[i]=1;
printf("gi=%d\n",i);
for(j=i+1;j<=n;j++){
if(!g[j]){
g[j]=1;
if(maxx>fuck()+mapp[i][j]){
/*
int x=i,y=j;
while(p[x][y]){
int s=x;
x=p[x][y];
printf("x =%d \n",x);
// matrix[x][y]++;
//matrix[y][x]++;
matrix[s][x]++;
matrix[x][s]++;
}
*/
/*
printf("i=%d,j=%d,d=%d\n",i,j,mapp[i][j]);
con[i][j]=1;
con[j][i]=1;
maxx=fuck()+mapp[i][j];
}
g[j]=0;
}
}
g[i]=0;
return maxx;
}
*/
int adde(int cn){//直接不计较复杂度的暴力递归。将奇点进行匹配得一个最小的
int ans=inf;
if(cn<2) return 0; //奇点个数小于2,无需匹配。
for(int i=1;i<=cn;i++){
if(sg[i]!=0){
for(int j=i+1;j<=cn;j++){
if(sg[j]!=0){
int tem1=sg[i],tem2=sg[j];
sg[i]=0;
sg[j]=0;
if(ans>adde(cn-2)+mapp[tem1][tem2]){
cont[i]=tem2; //第i个奇点匹配的奇点是第j个奇点
cont[j]=tem1; //第j个奇点匹配的奇点是第i个奇点
ans=adde(cn-2)+mapp[tem1][tem2];
}
sg[i]=tem1;
sg[j]=tem2;
}
}
}
}
return ans;
}
void addpath(int cn){
memset(vis,0,sizeof(vis));
for(int i=1;i<=cn;i++){
if(!vis[sg[i]]){
vis[sg[i]]=1;
vis[cont[i]]=1;
while(p[sg[i]][cont[i]]){
int sss=cont[i];
cont[i]=p[sg[i]][cont[i]];
matrix[sss][cont[i]]++;matrix[cont[i]][sss]++;
}
matrix[sg[i]][cont[i]]++;matrix[cont[i]][sg[i]]++;
}
}
}
void printf_path(){
//puts("fff");
printf("top=%d\n",top);
for(int i=top-1;i>=0;i--){
//printf("gg");
printf("%d",path[i]);
if(i) printf("->");
}
puts("");
}
void inif(){
for(int i=0;i<=N;i++){
for(int j=0;j<=N;j++){
mapp[i][j]=(i==j)?0:inf;
}
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
inif();
int i,beg,sum=0;
memset(matrix,0,sizeof(matrix));
memset(d,0,sizeof(d));
memset(sg,0,sizeof(sg));
memset(path,0,sizeof(path));
memset(p,0,sizeof(p));
memset(cont,0,sizeof(cont));
for(i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
d[a]++;
d[b]++;
matrix[a][b]=1;
matrix[b][a]=1;
mapp[a][b]=c;
mapp[b][a]=c;
gg[i].v=a;
gg[i].u=b;
gg[i].cost=c;
sum+=c;
}
beg=1;
int cnt=0;
for(i=1;i<=n;i++){
if(d[i]&1){
cnt++;
sg[cnt]=i;
beg=i;
}
}
if(!cnt){// 是欧拉图
printf("sum=%d\n",sum);
fleury(beg);
printf_path();
}
else { //不是欧拉图
floyed();
printf("sum=%d\n",sum+adde(cnt));
addpath(cnt);
fleury(beg);
//puts("--------------------");
printf_path();
}
}
return 0;
}
/*
1->2->1->6->5->4->3->2->3->7->4->5->6->7->1
*/