点击打开链接
题意:
有n个城市,m条路,每个城市最多走两次,求走完全部城市的最小路程。。。
因为没个城市最多走两次,所以要用3进制,求出1<<10的所有状态,并且此状态中每个城市走的次数。
状态方程dp[i+t3[k]][k]=max(dp[i][j]+map[j][k]);
dp[i][j]表示在状态i时走到j的最短路程。。。。
#include"stdio.h" #include"string.h" #define N 11 #define inf 0x1f1f1f1f int state[60000][N]; int dp[60000][N]; int map[N][N]; int t3[N]; int top,n; void init() { int i,j; top=0; for(i=0;i<60000;i++) { int t=i; for(j=0;j<10;j++) { state[i][j]=t%3; t/=3; } } t3[0]=1; for(i=1;i<N;i++) t3[i]=t3[i-1]*3; } int min(int a,int b) { return a<b?a:b; } int main() { int m; int i,j,k; init(); while(scanf("%d%d",&n,&m)!=-1) { memset(map,inf,sizeof(map)); memset(dp,inf,sizeof(dp)); while(m--) { scanf("%d%d%d",&i,&j,&k); i--;j--; if(map[i][j]>k)map[i][j]=map[j][i]=k; } for(i=0;i<n;i++)dp[t3[i]][i]=0; int ans=inf; for(i=0;i<t3[n];i++) { int f=1; for(j=0;j<n;j++) { if(state[i][j]==0)f=0; if(dp[i][j]==inf)continue; for(k=0;k<n;k++) { if(j==k)continue; if(state[i][k]>=2)continue; if(map[j][k]==inf)continue; dp[i+t3[k]][k]=min(dp[i][j]+map[j][k],dp[i+t3[k]][k]); } } if(f==1) { for(j=0;j<n;j++) ans=min(ans,dp[i][j]); } } if(ans>=inf)ans=-1; printf("%d\n",ans); } return 0; }