想象一下,要搞掉一个植物,必须先搞掉另一些植物……我们可以发现这是一个最大权闭合子图的问题。

最大权闭合子图的话,太空飞行计划问题是一个入门题,可以一看。

然而我们手玩一下样例就会惊恐地发现,保护关系出现了环

比如说:



从 i 到 j 的箭头是说要搞 i 就要先搞 j,这是为了和最大权闭合子图的模型对应。

要搞 3 就要先搞 4,要搞 4 就要先搞 5,要搞 5 就要先搞 3……简直是乱来……

这就像是一个无冷却食人花前面放一个坚果

所以就要删环了,把边倒过来拓扑排序一下,能被拓扑到的点就是合法的点。

然后就按照最大权闭合子图的套路搞一搞就是了。

记得开当前弧优化

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n, m, src[25][35], oea[605], ont, uu, vv, ind[605], ss, tt, tot, maxFlow, cnt, hea[605];
int lev[605], cur[605];
const int oo=0x3f3f3f3f;
queue<int> d;
bool vis[605];
struct Odge{
int too, nxt;
}odge[370005];
struct Edge{
int too, nxt, val;
}edge[800005];
int f(int i, int j){
return (i-1)*m+j;
}
void add_odge(int fro, int too){
odge[++ont].nxt = oea[fro];
odge[ont].too = too;
oea[fro] = ont;
}
void add_edge(int fro, int too, int val){
edge[cnt].nxt = hea[fro];
edge[cnt].too = too;
edge[cnt].val = val;
hea[fro] = cnt++;
}
void addEdge(int fro, int too, int val){
add_edge(fro, too, val);
add_edge(too, fro, 0);
}
void topsort(){
for(int i=1; i<=n*m; i++)
if(!ind[i])
d.push(i);
while(!d.empty()){
int x=d.front();
d.pop();
vis[x] = true;
for(int i=oea[x]; i; i=odge[i].nxt){
int t=odge[i].too;
ind[t]--;
if(!ind[t])
d.push(t);
}
}
}
bool bfs(){
memset(lev, 0, sizeof(lev));
lev[ss] = 1;
d.push(ss);
while(!d.empty()){
int x=d.front();
d.pop();
for(int i=hea[x]; i!=-1; i=edge[i].nxt){
int t=edge[i].too;
if(!lev[t] && edge[i].val>0){
lev[t] = lev[x] + 1;
d.push(t);
}
}
}
return lev[tt]!=0;
}
int dfs(int x, int lim){
if(x==tt) return lim;
int addFlow=0;
for(int &i=cur[x]; i!=-1; i=edge[i].nxt){
int t=edge[i].too;
if(lev[t]==lev[x]+1 && edge[i].val>0){
int tmp=dfs(t, min(lim-addFlow, edge[i].val));
edge[i].val -= tmp;
edge[i^1].val += tmp;
addFlow += tmp;
if(addFlow==lim) break;
}
}
return addFlow;
}
void dinic(){
while(bfs()){
for(int i=ss; i<=tt; i++) cur[i] = hea[i];
maxFlow += dfs(ss, oo);
}
}
int main(){
memset(hea, -1, sizeof(hea));
cin>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++){
scanf("%d", &src[i][j]);
int tmp;
scanf("%d", &tmp);
while(tmp--){
scanf("%d %d", &uu, &vv);
uu++; vv++;
add_odge(f(i,j), f(uu,vv));
ind[f(uu,vv)]++;
}
if(j>1) add_odge(f(i,j), f(i,j-1)), ind[f(i,j-1)]++;
}
topsort();
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(vis[f(i,j)])
for(int k=oea[f(i,j)]; k; k=odge[k].nxt){
int t=odge[k].too;
if(vis[t])
addEdge(t, f(i,j), oo);
}
ss = 0; tt = n * m + 1;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(vis[f(i,j)]){
if(src[i][j]>=0) addEdge(ss, f(i,j), src[i][j]), tot += src[i][j];
else addEdge(f(i,j), tt, -src[i][j]);
}
dinic();
cout<<max(tot-maxFlow, 0)<<endl;
return 0;
}

luogu2805 [NOI2009]植物大战僵尸的更多相关文章

  1. 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  2. P2805 [NOI2009]植物大战僵尸

    题目地址:P2805 [NOI2009]植物大战僵尸 最大权闭合子图 若有向图 \(G\) 的子图 \(V\) 满足: \(V\) 中顶点的所有出边均指向 \(V\) 内部的顶点,则称 \(V\) 是 ...

  3. COGS410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  4. BZOJ 1565: [NOI2009]植物大战僵尸

    1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2317  Solved: 1071[Submit][Stat ...

  5. 【刷题】BZOJ 1565 [NOI2009]植物大战僵尸

    Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻. ...

  6. 【bzoj1565】[NOI2009]植物大战僵尸

    1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2164  Solved: 1001[Submit][Stat ...

  7. 【最大权闭合子图 tarjan】bzoj1565: [NOI2009]植物大战僵尸

    dinic+tarjan板子练手题 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其 中P ...

  8. BZOJ1565: [NOI2009]植物大战僵尸

    Description Input Output 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. Sample Input 3 2 10 0 20 0 ...

  9. 【bzoj1565】 NOI2009—植物大战僵尸

    http://www.lydsy.com/JudgeOnline/problem.php?id=1565 (题目链接) 题意 给出$n*m$的棋盘,僵尸攻击每个格子可以获得$v$的分数,每个格子又会保 ...

随机推荐

  1. 8593 最大覆盖问题 two pointer

    8593 最大覆盖问题 时间限制:50MS  内存限制:1000K提交次数:193 通过次数:88 题型: 编程题   语言: G++;GCC;VC Description 输入格式 第1行是正整数n ...

  2. linux ln -s 软链接

     一.创建 ln -s 源文件 目标文件 当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的目录下用ln ...

  3. 自定义xml配置文件之dtd文件校验

    用了很多第三方库,也看了些源码,总是想如果自己写一个类似的库,读取xml配置文件(properties配置文件比较简单) 该如何给配置文件添加头,添加校验,因为xml配置文件相对于properties ...

  4. cucumber 文件目录结构和执行顺序

    引用链接:http://www.cnblogs.com/timsheng/archive/2012/12/10/2812164.html Cucumber是Ruby世界的BDD框架,开发人员主要与两类 ...

  5. eCharts基础知识

    eCharts插件介绍 http://echarts.baidu.com/tutorial.html#ECharts%20%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D

  6. java面试题(基础部分)

    1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...

  7. SQL注入原理与解决方法代码示例

    一.什么是sql注入? 1.什么是sql注入呢? 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网 ...

  8. Apache is running a threaded MPM, but your PHP module is not compiled to be threadsafe. you need to recompile php. pre-configuration failed

    手动配置想要组合版本的wamp环境时,在服务器上直接下载的几个安装包怎么都组合安装不成功,纠结很久,终于找到原因.配置apache支持php后apache一直无法成功启动.后来发现php是nts的版本 ...

  9. OpenCV中CvMat的初始化[转]

    一)cvCreateMat创建和分配数据CvCreateMat会创建CvMat,并为CvMat分配数据.cvCreateMat可以配合cvInitMatHeader来初始化CvMat对象.因为CvCr ...

  10. 新建maven的pom.xml第一行出错的解决思路

    前言:博主在想要用maven创建项目的时候,忘记之前已经安装过maven了,所以再安装了另一个版本的maven,导致在pom.xml的第一行总是显示某一个jar的zip文件读取不出来. 在网上找了很多 ...