链接:点击打开链接
题意:n个城市,m条路,每个城市最多经过两次,遍历所有城市最小的费用是多少
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int three[15]={1,3,9,27,81,243,729,2187,6561,19683,59049};
int d[20][20],dp[60005][15],vis[60005][15];
int main(){
char str[1005];
int V,m,i,j,k,s,u,v,w,ans,tmp,sign;
for(i=0;i<=three[10];i++){
tmp=i;
for(j=0;j<10;j++){
vis[i][j]=tmp%3;
tmp/=3;
}
}
while(scanf("%d%d",&V,&m)!=EOF&&V){
memset(d,INF,sizeof(d));
memset(dp,INF,sizeof(dp));
for(i=0;i<V;i++)
dp[three[i]][i]=0;
for(i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);
d[u-1][v-1]=min(d[u-1][v-1],w);
d[v-1][u-1]=d[u-1][v-1];
} //有重边
ans=INF;
for(s=0;s<three[V];s++){ //因为每个点最多经过两回,因此
sign=0; //就是TSP变为三进制,剩下跟二进
for(u=0;u<V;u++){ //制时一样
if(vis[s][u]==0)
sign=1;
if(dp[s][u]!=INF)
for(v=0;v<V;v++)
if(vis[s][v]!=2&&d[u][v]!=INF)
dp[s+three[v]][v]=min(dp[s+three[v]][v],dp[s][u]+d[u][v]);
}
if(sign==0) //最后不好判断是否有没走过的点
for(i=0;i<V;i++) //因此在中间判断
ans=min(ans,dp[s][i]);
}
if(ans>=INF)
puts("-1");
else
printf("%d\n",ans);
}
return 0;
}