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个点 ...
随机推荐
- Java虚拟机内存优化实践
前面一篇文章介绍了Java虚拟机的体系结构和内存模型,既然提到内存,就不得不说到内存泄露.众所周知,Java是从C++的基础上发展而来的,而C++程序的很大的一个问题就是内存泄露难以解决,尽管Java ...
- (转)android之Fragment(官网资料翻译)
Fragment要点 Fragment作为Activity界面的一部分组成出现 可以在一个Activity中同时出现多个Fragment,并且,一个Fragment亦可在多个Activity中使用. ...
- 正则表达式:网页爬虫:从TXT中获取邮箱地址(获取的练习,缺点:一行只能匹配一个)
import java.util.regex.*; import java.io.*; class L { public static void main(String[] args) throws ...
- Jsp中response对象的所有属性
所属接口:javax.servlet.http.HttpServletResponse,其父接口是ServletResponse,而且ServletResponse也现在只有唯一一个HttpServl ...
- 苹果有益让老iPhone变慢以迫使消费者购买新一代的iPhone?
首先,来一组来自谷歌Trends的图片.(谷歌Trends记录了某段时间内相关关键词搜索的次数.) 假设你做数据,那么你应该会有些感觉. 特别是第一幅图,它规律似乎比第二幅更明显,第二幅图仅仅是一个普 ...
- Java Web的数据库操作(一)
一.JDBC技术 1.JDBC简介 JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库交互,JDBC在Java程序与 ...
- Solr集成IK中文分词器
1.将IKAnalyzer-2012-4x.jar拷贝到example\solr-webapp\webapp\WEB-INF\lib下: 2.在schema.xml文件中添加fieldType: &l ...
- ftp nfs samba比较
首先从字面意思上区分一下:1. FTP(文件传输协议)2. NFS(网络文件系统)3. samba 即smb(服务信息块)协议其中FTP 是TCP/IP协议栈所提供的一种子协议,该子协议具体可以实现在 ...
- DateTimeBox( 日期时间输入框)
本节课重点了解 EasyUI 中 DateTimeBox(日期时间输入框)组件的使用方法,这个组件依赖于 DateBox(日期输入框)组件和 TimeSpinner(时间微调)组件. 一. 加载方式/ ...
- 打开新窗口(window.open)
open() 方法可以查找一个已经存在或者新建的浏览器窗口. 语法: window.open([URL], [窗口名称], [参数字符串]) 参数说明: URL:可选参数,在窗口中要显示网页的网址或路 ...