求助:剪枝dfs95pts
查看原帖
求助:剪枝dfs95pts
499231
Jacky2009楼主2022/5/19 00:16

如下. 思路:用一个数x(二进制)代表已发掘的藏宝洞,对边进行去重简化,然后剪枝(如果现在状态为x且花费大于目前状态为x是的最优解则剪枝),但是WA on 11


#include<bits/stdc++.h>
using namespace std;
#define int long long
struct edge{
	int to,w;
	edge(int T,int W){
		to=T;w=W;
	}
};
vector<edge>li[100005];
bool cmp1(edge a,edge b){
	if(a.to!=b.to)return a.to<b.to;
	return a.w<b.w;
}
bool cmp2(edge a,edge b){
	return a.w<b.w;
}
int minn=1145141919,n,m,a,b,c,mimn=1145141919;
int x=0;
int dis[100005];
int best[100005],b2[100005];
int tar[100005];
void dfs(long long x,int p){
	
	if(p>=minn)return;
	if(p>=b2[x])return;
	
	b2[x]=min(b2[x],p);
	if(x==(1<<(n+1))-2){
		
//	cout<<"Search "<<x<<" "<<"with the price of "<<p<<endl;
		minn=min(minn,p);
		return;
	}
	for(int i=1;i<=n;i++){
		if(x&(1<<i)){
			for(int j=0;j<li[i].size();j++){
				if((!(x&(1<<li[i][j].to)))&&(!dis[li[i][j].to])){
					dis[li[i][j].to]=dis[i]+1;
					int x2=x|(1<<li[i][j].to);
					dfs(x|(1<<li[i][j].to),p+dis[i]*li[i][j].w);
					dis[li[i][j].to]=0;
				}
			}
		}
	}
}
signed main(){
	memset(best,0,sizeof(best));
	cin>>n>>m;
	if(m==0){
		cout<<0;
		return 0;
	}
	for(int i=1;i<=m;i++){
		cin>>a>>b>>c;
		edge e=edge(1,2);
		e.to=b;
		e.w=c;
		li[a].push_back(e);
		e.to=a;
		li[b].push_back(e);
	}

	for(int i=1;i<=n;i++)sort(li[i].begin(),li[i].end(),cmp1);
	
/*	for(int i=1;i<=n;i++){
		for(int j=0;j<li[i].size();j++)cout<<"("<<li[i][j].to<<","<<li[i][j].w<<") ";
		cout<<endl;
	}
	cout<<endl;*/
	for(int i=1;i<=n;i++){
		edge e=li[i][0];
		for(int j=1;j<li[i].size();j++){
			if(li[i][j].to==e.to)li[i].erase(li[i].begin()+j),j--;
			else e=li[i][j];
		}
		sort(li[i].begin(),li[i].end(),cmp2);
	}
/*	for(int i=1;i<=n;i++){
		for(int j=0;j<li[i].size();j++)cout<<"("<<li[i][j].to<<","<<li[i][j].w<<") ";
		cout<<endl;
	}*/
	memset(b2,127,sizeof(b2));
	minn=114514191;
//	cout<<n<<endl;
	for(int i=1;i<=n;i++){
			dis[i]=1;
			dfs(1<<i,0);
			dis[i]=0;
	}
	cout<<minn<<endl;
}
2022/5/19 00:16
加载中...