2 1 1 2 100 3 2 1 2 40 2 3 50 3 3 1 2 3 1 3 4 2 3 10
100 90 7
又是不好好读题惹的祸==“he doesn't want to visit a city more than twice”!!!最多两次!!
开始以为是裸的二进制旅行商问题,还纳闷为啥第二题过的那么多,这个题没几个人做呢==然后又十分笨拙的写了一个四进制,本想省事0-未走;1-走过一次;2-走过两次;3-无意义。发现代码调试不成功orz 又努力的写三进制,所以说,预处理出两个数组是十分有必要的,科科~~
vis[][]表示当前状态某点走过几次
/************* hdu3001 2016.3.25 265MS 6704K 1638 B G++ *************/ #include <iostream> #include<cstdio> #include<cstring> using namespace std; #define inf 0x3f3f3f3f int min(int a,int b){if(a<b)return a;return b;} int num[11][11],dp[60000][11];//twice!! int vis[60000][11],state[12]; int n,m,ans; void init() { state[0]=1; for(int i=1;i<11;i++) state[i]=state[i-1]*3; for(int i=0;i<=state[10];i++) { int tmp=i; for(int j=0;j<=10;j++) { vis[i][j]=tmp%3; tmp/=3; } } } int main() { // freopen("cin.txt","r",stdin); init(); while(~scanf("%d%d",&n,&m)) { memset(num,inf,sizeof(num)); memset(dp,inf,sizeof(dp)); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(num[--a][--b]>c) num[a][b]=num[b][a]=c; } ans=inf; for(int i=0;i<n;i++)dp[state[i]][i]=0; for(int i=0;i<state[n];i++) { bool f=true; for(int j=0;j<n;j++) { if(vis[i][j]==0)f=false; if(dp[i][j]==inf)continue; for(int k=0;k<n;k++) if(j!=k) { if(vis[i][k]>=2)continue; if(num[j][k]==inf)continue; dp[i+state[k]][k]=min(dp[i+state[k]][k],dp[i][j]+num[j][k]); } } if(f) for(int j=0;j<n;j++) ans=min(ans,dp[i][j]); } if(ans<inf) printf("%d\n",ans); else printf("-1\n"); } return 0; }