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;
  }
}
原文地址:https://www.cnblogs.com/dowson/p/3313014.html