hdu4085
http://acm.hdu.edu.cn/showproblem.php?pid=4085
斯坦纳树。
用状压DP。
一共有2K个关键点:1,2...,K和N-K+1,N-K+2...,N,我们用一个2K位二进制数表示是否包含这些关键点。
F[i][state]表示一定包含i点,至少包含关键点state的生成树的最小费用,其中state是一个二进制数。
有2个转移:
F[i][state]=min{F[i][s]+F[i][state-s]}(其中s是state的子集)
F[i][state]=min{F[j][state]+cost}(其中i号点和j号点有边相连,费用为cost)
我们按state划分阶段,相同的state做SPFA。
现在我们已经求出F了。
记DP[state]表示至少包含关键点state时的生成树的最小费用,其实就是DP[state]=min{F[i][state]}(1<=i<=N)
我们还要判断state是否合法,就是人的个数和房子的个数相等,否则生成树就是不合法的。
但是现在DP[state]表示的还只是一颗生成树。
答案可以是森林。
我们可以从state的子集更新:DP[state]=min{DP[state],DP[s]+DP[state-s]}(其中s是state的子集)
这样就变成了森林了。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b) for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-;
inline int sgn(DB x){if(abs(x)<EPS)return ;return(x>)?:-;}
const DB Pi=acos(-1.0); inline int gint()
{
int res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
}
inline LL gll()
{
LL res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
} const int maxN=;
const int maxM=;
const int maxK=;
const int INF=0x3f3f3f3f; int N,M,K;
int bit[*maxK+];
int F[maxN+][two(*maxK)+];
int vis[maxN+][two(*maxK)+]; int now,first[maxN+];
struct Tedge{int v,cost,next;}edge[*maxM+]; inline void addedge(int u,int v,int cost)
{
now++;
edge[now].v=v;
edge[now].cost=cost;
edge[now].next=first[u];
first[u]=now;
} queue<PII>Q;
inline void SPFA()
{
while(!Q.empty())
{
int u=Q.front().fi,state=Q.front().se,i,v,cost;Q.pop();
vis[u][state]=;
for(i=first[u],v=edge[i].v,cost=edge[i].cost;i!=-;i=edge[i].next,v=edge[i].v,cost=edge[i].cost)
if(F[v][state]>F[u][state]+cost)
{
F[v][state]=F[u][state]+cost;
if(!vis[v][state])Q.push(PII(v,state)),vis[v][state]=;
}
}
} #define wei(v,k) ((v>>((k)-1))&1)
inline int check(int s)
{
int i,res=;
re(i,K+,*K)if(wei(s,i))res++;
re(i,,K)if(wei(s,i))res--;
return res==;
} int DP[two(*maxK)+]; int main()
{
freopen("hdu4085.in","r",stdin);
freopen("hdu4085.out","w",stdout);
int i,j;
for(int Case=gint();Case;Case--)
{
N=gint();M=gint();K=gint();
mmst(first,-);now=-;
re(i,,M){int u=gint(),v=gint(),cost=gint();addedge(u,v,cost);addedge(v,u,cost);}
mmst(F,0x3f);
mmst(bit,);
re(i,,K)bit[i]=two(i-),F[i][bit[i]]=;
re(i,,K)bit[N-K+i]=two(K+i-),F[N-K+i][bit[N-K+i]]=;
int state,maxstate=two(*K)-;
re(state,,maxstate)
{
re(i,,N)
{
for(int s=(state-)&state;s;s=(s-)&state)
upmin(F[i][state],F[i][s]+F[i][state-s]);
if(F[i][state]!=INF)Q.push(PII(i,state)),vis[i][state]=;
}
SPFA();
}
mmst(DP,0x3f);
re(state,,maxstate)re(i,,N)upmin(DP[state],F[i][state]);
re(i,,maxstate)if(check(i))
for(j=(i-)&i;j;j=(j-)&i)if(check(j))
upmin(DP[i],DP[j]+DP[i-j]);
if(DP[maxstate]==INF) PF("No solution\n"); else PF("%d\n",DP[maxstate]);
}
return ;
}
hdu4085的更多相关文章
- hdu4085 Peach Blossom Spring 斯坦纳树,状态dp
(1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s ...
- hdu4085 Peach Blossom Spring
Peach Blossom Spring http://acm.hdu.edu.cn/showproblem.php?pid=4085 Time Limit: 10000/5000 MS (Java/ ...
- hdu4085(斯坦纳树)
题意: 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价,从前k个点中任取一个使其和后k个点中的某一个点,通过边连接,并且必须是一一对应,问最小的代价是多少. 分 ...
- Minimal Steiner Tree ACM
上图论课的时候无意之间看到了这个,然后花了几天的时间学习了下,接下来做一个总结. 一般斯坦纳树问题是指(来自百度百科): 斯坦纳树问题是组合优化问题,与最小生成树相似,是最短网络的一种.最小生成树是在 ...
- HDU 4085 斯坦纳树+DP
https://cn.vjudge.net/problem/HDU-4085 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价 从前k个点中任取一个使其和后k个点 ...
随机推荐
- [饭后算法系列] 数组中"和非负"的最长子数组
1. 问题 给定一列数字数组 a[n], 求这个数组中最长的 "和>=0" 的子数组. (注: "子数组"表示下标必须是连续的. 另一个概念"子 ...
- openstack 手动 部署安装调试
Virtual Interface creation failed
- 基于网络的服装定制MTM系统研究 - 硕士论文 - 道客巴巴
国内的mtm系统_百度搜索 基于网络的服装定制MTM系统研究 - 硕士论文 - 道客巴巴 PDF文档(共76页) - 下载需1800积分 天津工业大学 硕士学位论文基于网络的服装定制MTM系统研究 姓 ...
- CentOS启动MySQL服务失败
:: mysqld_safe Starting mysqld daemon with databases from /data/mysql :: [Warning] Can't create test ...
- 详细介绍android rom移植知识普及
详细介绍android rom移植知识普及 最近接到很多兄弟们的求助,也回答过无数个和下面这个问题类似的问题: 如何编译android 原生代码得到一个rom,然后跑到某某手机上. 鉴于很多兄弟对这块 ...
- Hadoop 开源调度系统zeus(二)
紧跟之前Hadoop 开源调度系统zeus(一) 本节主要介绍一下zeus的架构: 先给一个zeus的架构图 无论Master还是Worker都有一套WEB UI,无论从哪个上面去看,看到的结果都是一 ...
- 栈溢出之rop到syscall
当程序开启了nx,但程序有syscall调用的时候.这时栈溢出的利用就可以通过rop来执行syscall的59号调用execve('/bin/sh',null,null),这是这次alictf一道pw ...
- Calendar( 日历)
本节课重点了解 EasyUI 中 Canlendar(日历)组件的使用方法,这个组件不依赖于其他组件.一. 加载方式//class 加载方式<div id="box" cla ...
- Mindset + Know-how+Concepture + Methodology+Technology
在做成都专案过程中深刻体会到一个IT全才应该具备Domain Know-how,拥有正确地理念是十分重要的, 我想只能是某几个领域,专案管理,专案运行中的各种手法,即Methodology,最后才是K ...
- Sass函数--数字函数
数字函数简介 Sass 中的数字函数提要针对数字方面提供一系列的函数功能: percentage($value):将一个不带单位的数转换成百分比值: round($value):将数值四舍五入,转换成 ...