P3959 宝藏 状压DP求助
查看原帖
P3959 宝藏 状压DP求助
1081095
Believe_in_dreams楼主2024/7/26 10:54

样例全过,自己造的hack(见代码结尾注释)也过了,但是提交30pts。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
	int s=0,f=1; char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
	return s*f;
}
const int N=15;
int n,m,x,y,z,p[N][N],dp[N][8000],dic[N][8000][N],minn=1e15;
void _input_(){ // 读入数据+判重边 
	n=read(); m=read();
	if(m==0){
		cout<<0;
		exit(0);
	}
	for(int i=1; i<=n; i++){
		for(int j=1; j<=n; j++)p[i][j]=1e9;
	}
	for(int i=1; i<=m; i++){
		x=read(),y=read(),z=read();
		p[x][y]=p[y][x]=min(p[x][y],z); // 判重边 
	}
}
void _dynamicp_(){ // 动态规划 
	for(int i=1; i<=n; i++){
		for(int j=0; j<(1<<n); j++){
			dp[i][j]=1e9;
			for(int k=1; k<=n; k++){
				dic[i][j][k]=1e9;
			}
		}
		dic[i][(1<<(i-1))][i]=0;
		dp[i][(1<<(i-1))]=0;
		for(int j=0; j<(1<<n); j++){
			for(int k=1; k<=n; k++){
				if(j&(1<<(k-1))) continue;
				for(int r=1; r<=n; r++){
					if(!(j&(1<<(r-1)))) continue;
					// 进行操作
					for(int q=1;q<=n;q++){
						if(q==k)dic[i][j|(1<<(k-1))][k]=min(dic[i][j|(1<<(k-1))][k],dic[i][j][r]+1);
						else dic[i][j|(1<<(k-1))][q]=min(dic[i][j|(1<<(k-1))][q],dic[i][j][q]);
					}
					dp[i][j|(1<<(k-1))]=min(dp[i][j|(1<<(k-1))],dp[i][j]+(dic[i][j][r]+1)*p[r][k]);
				}
			}
		}
		minn=min(minn,dp[i][(1<<n)-1]);
	} 
}

signed main(){
	_input_();
	_dynamicp_();
	cout<<minn;
	return 0;
} 
/*
  3 3
  1 3 1
  2 3 1
  1 2 9999
 */
2024/7/26 10:54
加载中...