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;
}

  

posted @ 2017-11-23 17:12  Stump  阅读(243)  评论(0编辑  收藏  举报