首页 > 代码库 > hdu 3001 状压DP
hdu 3001 状压DP
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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。