4 2 0 1 22 1 1 2 1 1 24 3 1 2 1 2 3 2 2 4 2 2 3 44 3 1 2 2 1 3 3 1 4 4 3 2 3 4
Case 1: -1 Case 2: 1 Case 3: 7 Case 4: 4
#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;
const int inf = 1<<29 ;
const int N = 17;
struct EDG{
int to,next,cost;
}edg[N*N];
int eid,head[N];
queue<int>id[1<<N];
int dp[1<<N][N],vist[1<<N][N],mincost[1<<N],f[1<<N];
void addEdg(int u,int v,int c){
edg[eid].to=v;
edg[eid].cost=c;
edg[eid].next=head[u];
head[u]=eid++;
}
int main(){
int T,t=0,n,m,a,b,c,mapt[N][N];
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
eid=0;
memset(head,-1,sizeof(head));
memset(vist,0,sizeof(vist));
for(int st=1; st<(1<<n); st++)
for(int i=0; i<n; i++)
dp[st][i]=inf;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
mapt[i][j]=inf;
while(m--){
scanf("%d%d%d",&a,&b,&c);
a--; b--;
if(mapt[a][b]>c)
mapt[a][b]=mapt[b][a]=c;
}
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
if(mapt[i][j]!=inf)
addEdg(i,j,mapt[i][j]);
int flag=0;
scanf("%d",&m);
while(m--){
scanf("%d",&a); a--; flag|=1<<a;
}
//路径压缩DP
dp[1][0]=0;
id[1].push(0);
vist[1][0]=1;
for(int st=1; st<(1<<n); st++)
{
while(!id[st].empty()){
int u=id[st].front();
id[st].pop();
vist[st][u]=0;
for(int i=head[u]; i!=-1; i=edg[i].next){
int v=edg[i].to;
if(dp[st|(1<<v)][v]>dp[st][u]+edg[i].cost){
dp[st|(1<<v)][v] = dp[st][u]+edg[i].cost;
if(vist[st|(1<<v)][v]==0)
vist[st|(1<<v)][v]=1,id[st|(1<<v)].push(v);
}
}
}
}
for(int st=1; st<(1<<n); st++)//找出一个最小花费到达的城市状态
{
mincost[st]=inf;
bool in=0;
for(int i=0; (1<<i)<=st; i++)
if((st&(1<<i))&&dp[st][i]!=inf)
{
if(mincost[st]>dp[st][i])
mincost[st]=dp[st][i];
}
f[st]=mincost[st];
}
//用01背包的方法
for(int k=1; k<3; k++)
for(int st=(1<<n)-1; st>0; st--)
if(st&1) //必须有1点
for(int s1=st; s1>0; s1=(s1-1)&st){
int s2=st^s1;
s2|=1; //保证了从1点出发
int tmp=f[s1|1];
if(tmp<mincost[s2])tmp=mincost[s2];
if(f[st]>tmp)f[st]=tmp;
}
int ans=inf ;
for(int st=1; st<(1<<n); st++)
if((st&flag)==flag){
if(ans>f[st])
ans=f[st];
}
if(ans==inf)ans=-1;
printf("Case %d: %d\n",++t,ans);
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 4640 Island and study-sister(状态压缩DP+路径压缩)经典 旅行商问题
原文地址:http://blog.csdn.net/u010372095/article/details/46894597