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点全部连通的最小花费以 ...
随机推荐
- Cocos2d-android (01) 创建一个简单的cocos2d应用程序
下载Cocos2d-android的源代码:cocos2d-android-1 git@github.com:ZhouWeikuan/cocos2d.git 将项目导入到eclipse中.运行实例: ...
- 3 years in Tencent game
心里一直有继续写博文的愿望,却一直被各种借口打断,现在回头一看,已经在腾讯待了3年半之久.3年半是个比较尴尬的时间点,不好意思说自己是游戏从业老兵,但又觉得自己对于行业已经看到比较清楚了:从当年毕业时 ...
- gcc 安装
最近在中标麒麟上面工作,结果发现上面gcc都没有,没有办法只好自己装(PS 中标麒麟:怪我咯) 资源:http://download.csdn.net/detail/jiahuat/8715413 按 ...
- Linux-sed用法
本文为转载,原地址:http://www.cnblogs.com/dong008259/archive/2011/12/07/2279897.html sed是一个很好的文件处理工具,本身是一个管道命 ...
- 深入理解HBase Memstore
2013/08/09 转发自http://www.cnblogs.com/shitouer/archive/2013/02/05/configuring-hbase-memstore-what-you ...
- pku3277 City Horizon
http://poj.org/problem?id=3277 线段树,离散化,成段更新 #include <stdio.h> #include <stdlib.h> #defi ...
- Android SDK无法更新解决方法
我这里主要说的是mac下如何设置Android SDK更新,windows下类似 首先说明为什么要这么麻烦,没办法身处在大天朝中,伟大的防火墙,苦逼的程序猿想要查点资料都是非常难的.不废话了,下面进入 ...
- cocos2dx使用了第三方库照样移植android平台-解决iconv库的移植问题
当我写这篇文章的时候我是怀着激动的心情的,因为我又解决了一个技术问题.你可能对题目还一知半解,这是什么意思,我之所以要写这篇文章就是要解决当我们在cocos2dx中使用了第三方库的时候,移植到andr ...
- TcxDBVerticalGrid优秀的编辑控件
- Python基础 条件、循环
1.条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. if if语句执行有个特点,它是从上往下判断,如果在某个判断上是True,把该判断对应的 ...