3001Travelling
这道题目跟之前的doing homework很像啊,同样的压缩方法,只是这个用三进制的格式
#include "iostream" #include "string.h" #define INF 10000000 using namespace std; int s[12]={0,1,3,9,27,81,243,729,2187,6561,19683,59049}; int dig[60000][11],dp[60000][11],map[11][11]; void work(){ int i,t,j; for(i=0;i<s[11];i++){ t=i; for(j=1;j<=10;j++){ dig[i][j]=t%3; t=t/3; } } } int min(int a,int b){return a>b?b:a;} int main(){ int n,m,i,a,b,c,j,k,flag; work(); while(cin>>n>>m){ memset(map,-1,sizeof(map)); for(i=0;i<m;i++){ cin>>a>>b>>c; if(map[a][b]==-1||map[a][b]>c){ map[a][b]=c;map[b][a]=c; } } for(i=0;i<s[n+1];i++){ for(j=1;j<=n;j++){ dp[i][j]=INF; } } for(i=1;i<=n;i++){ dp[s[i]][i]=0; } int MIN=INF; for(i=0;i<s[n+1];i++){ flag=1; for(j=1;j<=n;j++){ if(dig[i][j]==0)flag=0; if(dp[i][j]==INF)continue; for(k=1;k<=n;k++){ if(j==k)continue; if(map[j][k]==-1||dig[i][k]>=2)continue; int ans=i+s[k]; dp[ans][k]=min(dp[i][j]+map[j][k],dp[ans][k]); } } if(flag){ for(j=1;j<=n;j++) MIN=min(MIN,dp[i][j]); } } if(MIN==INF)cout<<-1<<endl; else cout<<MIN<<endl; } }