斯坦纳树模型 魔物消灭计划
Posted goto_1600
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斯坦纳树模型 魔物消灭计划相关的知识,希望对你有一定的参考价值。
链接
用于求必选点的最小生成树,复杂度指数,思想是dp,
d
p
[
i
]
[
j
]
代
表
以
i
为
根
j
状
态
的
必
选
点
dp[i][j]代表以i为根j状态的必选点
dp[i][j]代表以i为根j状态的必选点。状压处理两个转移,一种是同一个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)
2k∗n∗log(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
3k∗n
#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;
以上是关于斯坦纳树模型 魔物消灭计划的主要内容,如果未能解决你的问题,请参考以下文章