Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2338 Accepted Submission(s): 668
注意看清题目,并不是一个点只能走一次,而是一个点不能走超过两次。所以要用三进制表示状态。
/* * HDU3001 * 状态压缩DP */ #include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> using namespace std; const int MAXN=15; const int INF=0x3f3f3f3f; int g[MAXN][MAXN]; int dp[60000][MAXN]; int p[12]; int n; int a[12]; int ArrayToInt(int a[]) { int ret=0; for(int i=n-1;i>=0;i--) { ret*=3; ret+=a[i]; } return ret; } void intToArray(int x) { for(int i=0;i<n;i++) { a[i]=x%3; x/=3; } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); p[0]=1; for(int i=1;i<=11;i++)p[i]=3*p[i-1]; int u,v,w; int m; while(scanf("%d%d",&n,&m)==2) { memset(g,-1,sizeof(g)); while(m--) { scanf("%d%d%d",&u,&v,&w); u--; v--; if(g[u][v]==-1)g[u][v]=g[v][u]=w; else g[u][v]=g[v][u]=min(w,g[u][v]); } if(n==1) { printf("0\n"); continue; } memset(dp,-1,sizeof(dp)); int tot=0; for(int i=0;i<n;i++)tot+=p[i]; for(int i=0;i<n;i++)dp[p[i]][i]=0; int ans=INF; for(int i=0;i<p[n];i++) for(int j=0;j<n;j++) { intToArray(i); if(a[j]==0)continue; if(dp[i][j]<0)continue; bool full=true; for(int t=0;t<n;t++) if(a[t]==0) full=false; if(full)ans=min(ans,dp[i][j]); for(int k=0;k<n;k++) if(j!=k && g[j][k]!=-1 && a[k]<2) { a[k]++; int s=ArrayToInt(a); if(dp[s][k]==-1)dp[s][k]=dp[i][j]+g[j][k]; else dp[s][k]=min(dp[s][k],dp[i][j]+g[j][k]); a[k]--; } } if(ans==INF)printf("-1\n"); else printf("%d\n",ans); } return 0; }