NOIP2017 Day2T2
解题报告
状压DP=状压+记忆化搜索.
dfs时可以方便维护每种状态的每个点的depth。
dep[b[j]]=dep[a[i]]+1;
f[s|(1<<b[j])][st]=f[s][st]+dep[b[j]]*dis[a[i]][b[j]];
#include<stdio.h> #include<iostream> #include<algorithm> #define FOR(i,s,t) for(register int i=s;i<=t;++i) using namespace std; int ans,num; int n,m; const int inf=233333333; int dis[25][25]; int a[25],b[25],dep[25]; int f[1<<12][13]; int x,y,z; inline void dfs(int s,int st){ int a[13],b[13],cnta=0,cntb=0; FOR(i,0,n-1)(1<<i)&s?a[++cnta]=i:b[++cntb]=i; FOR(i,1,cnta)FOR(j,1,cntb){ if(dis[a[i]][b[j]]==inf)continue; dep[b[j]]=dep[a[i]]+1; if(f[s|(1<<b[j])][st]>f[s][st]+dep[b[j]]*dis[a[i]][b[j]]){ f[s|(1<<b[j])][st]=f[s][st]+dep[b[j]]*dis[a[i]][b[j]]; dfs(s|(1<<b[j]),st); } } } int main(){ scanf("%d%d",&n,&m); ans=inf; FOR(i,0,n)FOR(j,0,n)dis[i][j]=inf; FOR(i,0,n)dis[i][i]=0; while(m--){ scanf("%d%d%d",&x,&y,&z); --x;--y;dis[x][y]=min(dis[x][y],z);dis[y][x]=min(dis[y][x],z); } FOR(i,0,(1<<n)-1)FOR(j,0,n-1)f[i][j]=inf; FOR(i,0,n-1)f[1<<i][i]=0,dep[i]=0,dfs(1<<i,i); FOR(i,0,n-1)ans=min(ans,f[(1<<n)-1][i]); printf("%d\n",ans); return 0; }