斯坦纳树模型 魔物消灭计划

Posted goto_1600

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斯坦纳树模型 魔物消灭计划相关的知识,希望对你有一定的参考价值。

链接
用于求必选点的最小生成树,复杂度指数,思想是dp, d p [ i ] [ j ] 代 表 以 i 为 根 j 状 态 的 必 选 点 dp[i][j]代表以i为根j状态的必选点 dp[i][j]ij。状压处理两个转移,一种是同一个state的转移, d p [ x ] [ s t ] = d p [ y ] [ s t ] + d i s ( x , y ) dp[x][st]=dp[y][st]+dis(x,y) dp[x][st]=dp[y][st]+dis(x,y) 由最短路处理,这个部分 2 k ∗ n ∗ l o g ( n ) 2^k*n*log(n) 2knlog(n)一种是两个不相交子集的转移 d p [ x ] [ s t ] = d p [ x ] [ s u b s t ] + d p [ x ] [ s t   X O R   s u b s t ] dp[x][st]=dp[x][subst]+dp[x][st~XOR~subst] dp[x][st]=dp[x][subst]+dp[x][st XOR subst]这个部分 3 k ∗ n 3^k*n 3kn

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int,int> pii;
const int N = 110;
int a[N];
int id[N];
int dp[N][1050];
bool st[N];
vector<pair<int,int>>v[N];
priority_queue<pair<int,int>,vector<pii>,greater<pii>>q;
void dijkstra(int state)

	while(q.size())
	
		auto tt=q.top();
		q.pop();
		if(st[tt.second])	continue;
		st[tt.second]=true;
		for(auto j:v[tt.second])
		
			if(dp[j.first][state]>j.second+tt.first)
			
				dp[j.first][state]=j.second+tt.first;
				q.push(dp[j.first][state],j.first);
			
		
	

signed main()

	int n,m,k,x,y;
	cin>>n>>m>>k>>x>>y;
	memset(dp,0x3f,sizeof dp);
	int tot=k+2;
	// cout<<tot<<endl;
	for(int i=1;i<=n;i++)	
	
		cin>>a[i];
		if(i==x)	id[i]=k+1;
		else if(i==y)	id[i]=k+2;
		else if(a[i]==0)
		
			id[i]=++tot;
		
		else
			id[i]=a[i];
	
	for(int i=1;i<=m;i++)
	
		int x,y;
		cin>>x>>y;
		int w;
		cin>>w;
		if(x==y)	continue;
		v[id[x]].push_back(id[y],w);
		v[id[y]].push_back(id[x],w);
	
	int allmask=(1<<(k+2))-1;
	for(int i=1;i<=tot;i++)
	
		if(i<=k+2)
		
			dp[i][1<<(i-1)]=0;	
		
		else
			dp[i][0]=0;
		
	
	for(int i=1;i<=allmask;i++)
		for(int j=i;j;j=(j-1)&i)
			for(int t=1;t<=tot;t++)
				dp[t][i]=min(dp[t][i],dp[t][j]+dp[t][i^j]);
		for(int j=1;j<=tot;j++)
		
			st[j]=false;
			if(dp[j][i]!=0x3f3f3f3f)
				q.push(dp[j][i],j);
		
		dijkstra(i);
	
	int res=2e9;
	for(int i=1;i<=tot;i++)
	
		res=min(res,dp[i][allmask]);
	
	cout<<res<<endl;
	return 0;





以上是关于斯坦纳树模型 魔物消灭计划的主要内容,如果未能解决你的问题,请参考以下文章

斯坦纳树模型 魔物消灭计划

WC 2008 观光计划(斯坦纳树)

BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树

BZOJ_2595_[Wc2008]游览计划_斯坦纳树

[WC2008]游览计划 「斯坦那树模板」

bzoj2595: [Wc2008]游览计划 斯坦纳树