(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的更多相关文章

  1. 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]  ...

  2. hdu4085 Peach Blossom Spring

    Peach Blossom Spring http://acm.hdu.edu.cn/showproblem.php?pid=4085 Time Limit: 10000/5000 MS (Java/ ...

  3. BZOJ 4006 [JLOI2015]管道连接(斯坦纳树+子集DP)

    明显是一道斯坦纳树的题. 然而这题只需要属性相同的点互相连接. 我们还是照常先套路求出\(ans[s]\). 然后对\(ans[s]\)做子集DP即可. 具体看代码. #include<iost ...

  4. hdu4085(斯坦纳树)

    题意: 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价,从前k个点中任取一个使其和后k个点中的某一个点,通过边连接,并且必须是一一对应,问最小的代价是多少. 分 ...

  5. BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树

    [题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...

  6. 洛谷P3264 [JLOI2015]管道连接 (斯坦纳树)

    题目链接 题目大意:有一张无向图,每条边有一定的花费,给出一些点集,让你从中选出一些边,用最小的花费将每个点集内的点相互连通,可以使用点集之外的点(如果需要的话). 算是斯坦纳树的入门题吧. 什么是斯 ...

  7. HDOJ 4085 Peach Blossom Spring

    discriptionTao Yuanming(365-427) was a Chinese poet of Eastern Jin dynasty. One of his most famous w ...

  8. HDU 4085 斯坦纳树+DP

    https://cn.vjudge.net/problem/HDU-4085 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价 从前k个点中任取一个使其和后k个点 ...

  9. 【BZOJ2595】游览计划(状压DP,斯坦纳树)

    题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...

随机推荐

  1. iOS学习笔记之Category

    iOS学习笔记之Category 写在前面 Category是类别(也称为类目或范畴),使用Category,程序员可以为任何已有的类添加方法.使用类别可以对框架提供的类(无法获取源码,不能直接修改) ...

  2. Intellij IDEA开发第一个Android应用

    1.创建一个项目 File——>New Project——>.......——>Finish 2.创建模块 3.MyActivity.java package com.example ...

  3. anible包模块管理

    ansible使用包管理模块 一般使用的包管理模块的RPM,和YUM 参数 必填 默认 选择 说明 Conf_file No YUM的配置文件 Disable_dbg_check No No Yes/ ...

  4. Intent传输数据的补充

    发现用intent的putExtra()或者putExtras()传输的都是基本数据类型. 如果要传输自定义数据类型,就要用到其他方法,老罗介绍的大概有3种: 1.  静态变量 2.  全局变量 3. ...

  5. Research on Unsupervised Word Alignment Based on Inversion Transduction Grammar

    1.提出了一种基于特征函数和反向转录文法(ITG)的无监督词对齐模型,使用对数线性模型对文法规则的概率建模,先验知识可以通过特征函数的形式加入到模型里面,而模型仍然可以进行无监督训练.2. 在模型的参 ...

  6. Android APP的安装路径

    转载自:http://blog.csdn.net/libaineu2004/article/details/25247711 一.安装路径在哪? Android应用安装涉及到如下几个目录: syste ...

  7. (翻译)从底层了解ASP.NET体系结构 [转]

    转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...

  8. 【数据结构与算法分析——C语言描述】第一章总结 引论

    这一章主要复习了一些数学知识,像指数.对数.模运算.级数公式:还有2种证明方法,归纳假设法和反证法.所幸以前学过,重新拾捡起来也比较轻松. 简要地复习了递归,提出了编写递归例程的四条基本法则: 基准情 ...

  9. HDU2033 人见人爱A+B 分类: ACM 2015-06-21 23:05 13人阅读 评论(0) 收藏

    人见人爱A+B Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Su ...

  10. 可迭代的集合类型使用foreach语句

    在学习算法这本书图论那一部分的时候,接触到了几个类似for(int w:G.adj(v)),的语句,不是很理解,就去百度,发现这是一种叫做foreach的语法,在书的76页有讲到,但是之前没认真看书, ...