1. 程式人生 > >洛谷3959 寶藏(狀壓DP bczd)

洛谷3959 寶藏(狀壓DP bczd)

傳送門

【題目分析】

看看這隻有12的資料規模,那麼狀壓沒跑了。

轉移也很好想,列舉起點,更新dp值。。。。。。然後就被hack了。。。。。

hack資料:6 6 1 2 100 2 3 1 2 4 10 3 4 10 3 5 100 4 6 10000

所以這就是所謂的錯誤做法又沒卡。。。。。。

所以放一篇寫的很好的部落格:傳送門

所以這裡我就放一個狀壓的程式了qwq(至於膜你退火什麼的不會啊qwq

【程式碼~】

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1<<12;
const int MAXM=2e3+10;
const int INF=0x3f3f3f3f;

int n,m,cnt,ans=INF;
int dp[MAXN];
int head[20];
int nxt[MAXM],to[MAXM],w[MAXM],depth[MAXN];
int dis[15][15];

int Read(){
	int i=0,f=1;
	char c;
	for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
	if(c=='-')
	  f=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar())
	  i=(i<<3)+(i<<1)+c-'0';
	return i*f;
}

void add(int x,int y,int z){
	nxt[cnt]=head[x];
	head[x]=cnt;
	to[cnt]=y;
	w[cnt]=z;
	cnt++;
}

void dfs(int status){
	for(int i=1;i<=n;++i){
		if(status&(1<<(i-1))){
			for(int j=1;j<=n;++j){
				if(!(status&(1<<(j-1)))&&dis[i][j]!=INF&&dp[status|(1<<(j-1))]>dp[status]+dis[i][j]*depth[i]){
					dp[status|(1<<(j-1))]=dp[status]+dis[i][j]*depth[i];
					int x=depth[j];
					depth[j]=depth[i]+1;
					dfs(status|(1<<(j-1)));
					depth[j]=x;
				}
			}
		}
	}
}

int main(){
	memset(dis,INF,sizeof(dis));
	memset(head,-1,sizeof(head));
	n=Read(),m=Read();
	for(int i=1;i<=m;++i){
		int x=Read(),y=Read(),z=Read();
		dis[x][y]=min(z,dis[x][y]);
		dis[y][x]=min(z,dis[y][x]);
	}
	int mask=1<<n;
	for(int i=1;i<=n;++i){
		memset(dp,INF,sizeof(dp));
		dp[1<<(i-1)]=0;
		memset(depth,0,sizeof(depth));
		depth[i]=1;
		dfs(1<<(i-1));
		ans=min(ans,dp[mask-1]);
	}
	cout<<ans;
	return 0;
}