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[i]]);,后面的要 |s[i],保证状态的正确
(3)INF初始化CLR(dp, 0x3f)
(4)注意斯坦纳树状态理解,分层松弛的理解
参考:http://endlesscount.blog.163.com/blog/static/821197872012525113427573/
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s) typedef long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-10;
const int MAXN = 1000010; struct node{
int to, next, l;
};
int tol;
node adj[2010];
int head[55];
void init_adj()
{
tol = 0;
CLR(head, -1);
}
void add_edge(int x, int y, int ll)
{
adj[tol].to = y;
adj[tol].l = ll;
adj[tol].next = head[x];
head[x] = tol++;
}
int dp[55][1 << 11];
queue<int>q;
bool inq[55][1 << 11];
int d[1 << 11];
int s[55];
int n, m, k;
int cnt, ALL; bool check(int ss)
{
int num = 0;
for (int i = 0; i < cnt; i++)
if (ss & (1 << i))
num += i < k ? 1 : -1;
if (!num) return 1;
return 0;
} void spfa()
{
while (!q.empty())
{
int u = q.front(); q.pop();
int ui = u / 10000;
int uss = u % 10000;
inq[ui][uss] = 0;
for (int r = head[ui]; r != -1; r = adj[r].next)
{
int vi = adj[r].to;
int vss = uss | s[vi];
if (dp[vi][vss] > dp[ui][uss] + adj[r].l)
{
dp[vi][vss] = dp[ui][uss] + adj[r].l;
if (vss == uss && !inq[vi][vss]) /// 同层且不再队列中
{
inq[vi][vss] = 1;
q.push(vi * 10000 + vss);
}
}
}
}
} void solve()
{
while (!q.empty()) q.pop();
CLR(inq, 0);
FE(ss, 0, ALL)
{
FE(i, 1, n)
{
for (int rr = ss & (ss - 1); rr; rr = (rr - 1) & ss)///ss
dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s[i]]);
if (dp[i][ss] < INF)
q.push(i * 10000 + ss), inq[i][ss] = 1;
}
spfa();
} CLR(d, 0x3f);
FE(ss, 0, ALL) FE(j, 1, n)
d[ss] = min(d[ss], dp[j][ss]); REP(ss, ALL + 1)
for(int rr = ss & (ss - 1); rr; rr = (rr - 1) & ss)
if (check(rr) && check(ss ^ rr))
d[ss] = min(d[ss], d[rr] + d[ss ^ rr]); if (d[ALL] == INF) printf("No solution\n");
else printf("%d\n", d[ALL]);
} void init()
{
int x, y, l;
init_adj();
RIII(n, m, k);
while (m--)
{
RIII(x, y, l);
add_edge(x, y, l);
add_edge(y, x, l);
} cnt = 2 * k;
ALL = (1 << cnt) - 1; CLR(s, 0);
CLR(dp, 0x3f); FE(i, 1, k)///集合
{
s[i] = 1 << (i - 1);
dp[i][s[i]] = 0;
s[n - k + i] = 1 << (k + i - 1);
dp[n - k + i][s[n - k + i]] = 0;
}
} int main ()
{
int T;
RI(T);
while (T--)
{
init();
solve();
}
return 0;
}
hdu4085 Peach Blossom Spring 斯坦纳树,状态dp的更多相关文章
- HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA
状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 当中k和l是对j的一个划分 依照边进行松弛 dp[i][j] ...
- hdu4085 Peach Blossom Spring
Peach Blossom Spring http://acm.hdu.edu.cn/showproblem.php?pid=4085 Time Limit: 10000/5000 MS (Java/ ...
- BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)
明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...
- hdu4085(斯坦纳树)
题意: 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价,从前k个点中任取一个使其和后k个点中的某一个点,通过边连接,并且必须是一一对应,问最小的代价是多少. 分 ...
- BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树
[题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...
- 洛谷P3264 [JLOI2015]管道连接 (斯坦纳树)
题目链接 题目大意:有一张无向图,每条边有一定的花费,给出一些点集,让你从中选出一些边,用最小的花费将每个点集内的点相互连通,可以使用点集之外的点(如果需要的话). 算是斯坦纳树的入门题吧. 什么是斯 ...
- HDOJ 4085 Peach Blossom Spring
discriptionTao Yuanming(365-427) was a Chinese poet of Eastern Jin dynasty. One of his most famous w ...
- HDU 4085 斯坦纳树+DP
https://cn.vjudge.net/problem/HDU-4085 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价 从前k个点中任取一个使其和后k个点 ...
- 【BZOJ2595】游览计划(状压DP,斯坦纳树)
题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...
随机推荐
- Delphi MDI程序 父窗体如何调用当前活动子窗体的函数/过程
一个MDI文本文件编辑器打开了N个子窗体子窗体的.pas文件有一些public的过程和函数我想在父窗体调用当前活动的子窗体函数我用Self.ActiveChildForm无法调用直接frmEdit.x ...
- LR录制脚本IE不能打开解决方法
运行环境:win7 64位 解决方法:1.卸载IE11 2.计算机——属性——高级系统设置——性能里的设置——数据执行保护——选择“为除下列选定程序之外的所有程序和服务启用”——添加IE浏览器和VUG ...
- 大端小端(Big- Endian和Little-Endian)[转]
原文出处: 字节序(Endian),大端(Big-Endian),小端(Little-Endian) http://www.cppblog.com/tx7do/archive/2009/01/06/ ...
- MSDN 中 对vector::erase()的解释.xml
pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9; ...
- Prototype入门
官网地址:http://prototypejs.org/ Prototype降低了客户端web编程的复杂性.为了解决现实存在的一些问题,Prototype对浏览器的脚本环境做了一些扩展,对原先笨拙的A ...
- os和os.path模块
Os和os.path模块函数 1. Os模块 函数 描述 文件处理 Mkfifo()/mknod() 创建命名管道/创建文件系统节点 Remove()/unlink() 删除文件 Renam ...
- javascript函数sort
sort函数用于对数组的元素进行排序 语法:arrayObject.sort(sortby); 参数sortby可选,规定排序顺序,必须是函数. 如果调用该方法时没有使用参数,将按照字幕顺序进行排序, ...
- VS常用技巧
VS2005代码编辑器的展开和折叠代码确实很方便和实用.以下是展开代码和折叠代码所用到的快捷键,很常用: Ctrl + M + O: 折叠所有方法 Ctrl + M + M: 折叠或者展开当前方法 C ...
- AI钻石风格logo教程
最终图像 与往常一样,这是我们要创建的最终图像: Step 1 按Ctrl+ N创建新文档.从单位下拉菜单中选择像素,在宽度和高度框中输入600,然后单击高级按钮.选择RGB,屏幕(72 PPI),并 ...
- with 语句
with 语句用于设置代码在特定对象中的作用域. 它的语法: with (expression) statement例如: var sMessage = "hello"; with ...