BZOJ3058 四叶草魔杖
Poetize11的T3
蒟蒻非常欢脱的写完了费用流,发现。。。边的cost竟然只算一次!!!
然后就跪了。。。
Orz题解:"类型:Floyd传递闭包+最小生成树+状态压缩动态规划
首先Floyd传递闭包,然后找出所有∑ai =0的集合,对每个集合求出最小生成树,就是该集合内部能量转化的最小代价。
然后把每个集合当做一个物品,做一遍类似背包的DP。DP过程中F[i]表示二进制状态为i(1表示该点选了,0表示没选)时已选的点之间能量转化的最小代价。然后枚举所有的j,如果i and j=0,那么用F[i]+F[j]更新一下F[i or j]。
直接这样DP可能会超时,我们不妨去除一些诸如ai=0之类的点。然后把∑ai=0的集合存进数组,DP时只循环数组内的状态来加速。"
原来Floyd还有如此妙用= =
/**************************************************************
Problem: 3058
User: rausen
Language: C++
Result: Accepted
Time:36 ms
Memory:1580 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int N = , M = ; int n, m, p, q, l, t;
int a[N], d[N][N], g[N], b[M], c[N], f[M], s[M];
bool vis[N]; inline int read() {
int x = , sgn = ;
char ch = getchar();
while (ch < '' || '' < ch) {
if (ch == '-') sgn = -;
ch = getchar();
}
while ('' <= ch && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return sgn * x;
} int prim() {
int res = , i, j, k, tmp;
memset(vis, , sizeof(vis));
memset(g, 0x3f, sizeof(g));
g[c[]] = ;
for (i = ; i <= m; ++i) {
tmp = 0x3fffffff;
for (j = ; j <= m; ++j)
if (!vis[c[j]] && g[c[j]] < tmp) tmp = g[c[j]], k = c[j];
if (tmp == 0x3f3f3f3f) return -;
res += tmp;
vis[k] = ;
for (j = ; j <= m; ++j)
if (!vis[c[j]] && g[c[j]] > d[k][c[j]])
g[c[j]] = d[k][c[j]];
}
return res;
} void Floyd() {
int i, j, k;
for (k = ; k <= n; ++k)
for (i = ; i <= n; ++i)
for (j = ; j <= n; ++j)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
} int main() {
int i, j, k, x, y, maxi;
n = read(), m = read();
memset(d, 0x3f, sizeof(d));
t = ( << n) - ;
for (i = ; i <= n; ++i) {
if (!(a[i] = read())) t ^= << i - ;
d[i][i] = ;
}
for (i = ; i <= m; ++i) {
x = read() + , y = read() + ;
d[x][y] = d[y][x] = read();
}
Floyd();
memset(f, 0x3f, sizeof(f));
f[] = ;
for (p = i = , maxi = << n; i < maxi; ++i) {
for (j = ; j < n; ++j)
if ((i >> j & ) && !a[j + ]) break;
if (j < n) continue;
b[i] = ;
for (m = j = ; j < n; ++j)
if (i >> j & ) b[i] += a[j + ], c[++m] = j + ;
if (b[i]) continue;
b[i] = prim();
s[++p] = i;
}
for (q = ; q <= p; ++q) {
i = s[q], k = b[i];
if (k == -) continue;
for (l = ; l <= p; ++l) {
j = s[l];
if (!(i & j)) f[i | j] = min(f[i | j], f[j] + k);
}
}
if (f[t] == 0x3f3f3f3f) puts("Impossible");
else printf("%d\n", f[t]);
}
BZOJ3058 四叶草魔杖的更多相关文章
- BZOJ_3058_四叶草魔杖_kruscal+状压DP
BZOJ_3058_四叶草魔杖_kruscal+状压DP Description 魔杖护法Freda融合了四件武器,于是魔杖顶端缓缓地生出了一棵四叶草,四片叶子幻发着淡淡的七色光.圣剑护法rainbo ...
- [tyvj2054] 四叶草魔杖 (最小生成树 状压dp)
传送门 Background 陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,到达了目的地,面前出现了一座城堡和小溪田园,城堡前的木牌上写着"Poetic Island&q ...
- BZOJ.3058.四叶草魔杖(Kruskal 状压DP)
题目链接 \(2^{16}=65536\),可以想到状压DP.但是又有\(\sum A_i\neq 0\)的问题.. 但是\(2^n\)这么小,完全可以枚举所有子集找到\(\sum A_i=0\)的, ...
- tyvj 2054 [Nescafé29]四叶草魔杖——最小生成树+状压dp
题目:http://www.joyoi.cn/problem/tyvj-2054 枚举点集,如果其和为0,则作为一个独立的块求一下最小生成树.因为它可以不和别的块连边. 然后状压dp即可. 别忘了判断 ...
- tyvj 2054 [Nescafé29]四叶草魔杖【克鲁斯卡尔+状压dp】
传送:http://www.joyoi.cn/problem/tyvj-2054 来自lyd课件: 所以先预处理出各个sum为0的块,然后状压dfs取min来得到答案 #include<iost ...
- tyvj2054 四叶草魔杖——连通块 & 状压DP
题目:http://www.joyoi.cn/problem/tyvj-2054 把点分成几个连通块,和为0的几个点放在一块,在块内跑最小生成树作为这个块的代价: 然后状压DP,组成全集的最小代价就是 ...
- bzoj5038 四叶草魔杖
很有意思的最小生成树啊. 网上的题解大多是状压+最小生成树,经过我的试验,其实只要把每个联通块找出来,一个个做一次就可以了. 放一个状压的.懒得再写一个搜索找联通块 #include<cstdi ...
- [tyvj-2054][Nescafé29]四叶草魔杖 费用流
lyd讲的最小生成树的题. 道理我都懂,费用流多好写,又好调.但和一般费用流不一样的就是它走过一次后费用需调成0,但是再等回流,就恢复原状即可. #include <queue> #inc ...
- NOIP系列复习及题目集合
首先是我的酱油记了啦~: Xs的NOIP2014酱油记,持续更新中 知识点方面: noip知识点总结之--贪心 noip知识点总结之--线性筛法及其拓展 noip知识点总结之--欧几里得算法和扩展欧几 ...
随机推荐
- AngularJS Protractor
官网地址:http://www.protractortest.org/ 1. 预备环境 protractor 是一个 Node.js 程序,为了运行 protractor ,你首先需要 Node 环境 ...
- LINQ之路 4:LINQ方法语法
书写LINQ查询时又两种语法可供选择:方法语法(Fluent Syntax)和查询语法(Query Expression). LINQ方法语法是非常灵活和重要的,我们在这里将描述使用链接查询运算符的方 ...
- IP地址匹配
问题描述: 在路由器中,一般来说转发模块采用最大前缀匹配原则进行目的端口查找,具体如下: IP地址和子网地址匹配: IP地址和子网地址所带掩码做AND运算后,得到的值与子网地址相同,则该IP地址与该子 ...
- SurfaceHolder.Callback
Class Overview A client may implement this interface to receive information about changes to the sur ...
- haskell rust相关文章
Combining Rust and Haskell http://tab.snarc.org/posts/haskell/2015-09-29-rust-with-haskell.html
- 转自“脚本之家”!!JDBC之PreparedStatement类中预编译的综合应用解析
JDK 文档:SQL 语句被预编译并存储在 PreparedStatement 对象中(PreparedStatement是存储在JDBC里的,初始化后,缓存到了JDBC里),然后可以使用此对象多次高 ...
- An unknown server-side error occurred while processing the command.处理
在调用resetAPP()时,报错:An unknown server-side error occurred while processing the command. 怎么解决呢?请看: 额,Ap ...
- 1到N中1出现的次数
这个问题关键在于好好分析一些样例如: 给定123这个数,你说这个从1到123所有数字中,1出现的次数是多少? 首先我们要分析个位上1出现的次数,我们看看什么情况下个位出现1: 1,11,21,31,4 ...
- java 异常2
自定义异常类: import java.util.Scanner; /** * Created by lenovo on 2016/8/12. */ class NoMoneyException ex ...
- 【转】 Linux chmod命令
在Unix和Linux的各种操作系统下,每个文件(文件夹也被看作是文件)都按读.写.运行设定权限.例如我用ls -l命令列文件表时,得到如下输出:-rw-r--r-- 1 apple users 22 ...