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
网上说是DP+状压,结果用bfs+状压水过了。。
开始时把每一个点都入队,模拟3进制处理每个状态,最后+优化。
#include<iostream> #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> using namespace std; #define N 12 #define LL long long const int inf=0x3fffffff; int g[N][N]; int n,m,ans; int mark[N][60000]; struct node { int x,t,s,cnt; //位置、时间、状态、个数 friend bool operator<(node a,node b) { return a.t>b.t; } }; int gettmp(int x,int k) //得到X在3进制下的第K位是多少 { int t; while(x) { t=x%3; k--; if(k==0) break; x/=3; } return k?0:t; } void inti() //初始化数组 { int i,j; for(i=1;i<=n;i++) { for(j=0;j<(int)pow(3,n);j++) mark[i][j]=inf; } } void bfs() { int i; priority_queue<node>q; node cur,next; for(i=1;i<=n;i++) { cur.x=i; cur.s=pow(3,(i-1)); cur.t=0; cur.cnt=1; q.push(cur); mark[i][0]=0; } while(!q.empty()) { cur=q.top(); q.pop(); for(i=1;i<=n;i++) { if(g[cur.x][i]==inf) continue; next.cnt=cur.cnt; next.s=cur.s; next.t=cur.t+g[cur.x][i]; if(ans<next.t) //优化很重要 continue; next.x=i; int t=gettmp(next.s,i); if(t>=2) continue; next.s+=pow(3,(i-1)); if(t==0) { next.cnt++; if(next.cnt==n) { ans=min(ans,next.t); continue; } } if(next.t<mark[i][next.s]) { mark[i][next.s]=next.t; q.push(next); } } } } int main() { int a,b,c,i,j; while(scanf("%d%d",&n,&m)!=-1) { for(i=0;i<=n;i++) for(j=1;j<=n;j++) g[i][j]=(i==j?0:inf); for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); g[a][b]=g[b][a]=min(g[a][b],c); } ans=inf; inti(); bfs(); if(ans==inf) ans=-1; printf("%d\n",ans); } return 0; }
hdu 3001 Travelling (bfs+状态压缩)
原文:http://blog.csdn.net/u011721440/article/details/39738173