http://acm.hdu.edu.cn/showproblem.php?pid=3001
因为数组开的不够大,WA了1个多小时没查出来哪里错误。。。后来发现 是3^n 我直接1<<n。。。二进制跟三进制弄混了
学到:1、经过每个点k次 转化为k进制就可以了,其他类比TSP的状压
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
using namespace std;
#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdin)
const int MAXN = 12;
const int INF = 0x1f1f1f1f;//可以用memset
int dis[MAXN][MAXN];
char thr[59050][MAXN];
int n,m,dp[59050][MAXN];
int cal(int x)
{
int tmp=1;
for(int i=0;i<x;i++)
tmp*=3;
return tmp;
}
void init()
{
rep(i,0,n+1)
rep(j,0,n+1)
dis[i][j]=INF;
memset(thr,0,sizeof(thr));
}
int main()
{
//IN("hdu3001.txt");
int len,u,v,ans;
while(~scanf("%d%d",&n,&m))
{
init();
ans=INF;
rep(i,0,m)
{
scanf("%d%d%d",&u,&v,&len);
dis[v-1][u-1]=dis[u-1][v-1]=min(dis[u-1][v-1],len);
}
int tmp2=1,tmp,cnt,cc,pos;
for(int i=0;i<n;i++)/
tmp2*=3;
memset(dp,INF,sizeof(dp));
rep(s,0,tmp2)
{
int flag=1;
cnt=cc=pos=0;
tmp=s;
while(tmp)
{
if(tmp%3)
{
thr[s][cnt]=tmp%3;
pos=cnt;
cc++;
}
tmp/=3;
cnt++;
}
//
/* printf("#s=%d ",s);
for(int i=0;i<n;i++)
printf("%d",thr[s][i]);
putchar('\n');*/
/
if(cc==1 && thr[s][pos]==1){dp[s][pos]=0;continue;}
rep(i,0,n)
{
if(!thr[s][i]){flag=0;continue;}
rep(j,0,n)
{
if(!thr[s][j] || i == j || dis[i][j]==INF)continue;///
if(thr[s][i]<=2)
{
dp[s][i]=min(dp[s-cal(i)][j]+dis[j][i],dp[s][i]);
}
}
}
//test
if(flag)
{
for(int k=0;k<n;k++)
ans=min(ans,dp[s][k]);
}
}
if(ans==INF)printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}