[BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]
Description
Solution
em本题知识点是用网络流求最大点权闭合子图。
闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中。
建图:运用最小割思想,将S向点权为正的点连边,流量为点权;点权为负的点向T连边,流量为点权的绝对值;原图之间的边流量为inf(表明不能割)。答案就是所有正点权之和-该网络流图的最小割(证明还未补qaq)
是不是觉得这个闭合图定义特别的眼熟?似乎可以套在这道题上。(题意:假如你要吃掉某个植物,需要先吃掉这个植物对应的集合,求最大的能源收入。)假如植物v保护u【ps:在u后面的植物也算作保护u】,则连边u->v。
当然需要注意,有些植物是RMB玩家哈哈(就是,它们的保护关系可以构成一个环),则这些植物和它们所保护的植物都是不能被吃掉的。RMB玩家可以用拓扑排序完美KO(当然,要把边反向建。原因。。因为我们还要找出所有环上植物们"所保护的植物")
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int inf=1e9; int h[],tot=;
struct pas{int x,y,nxt,w,op,cost;}g[];
int dep[],S,T;
queue<int>q;
struct DINIC{
bool bfs()
{
int x;
memset(dep,,sizeof(dep));dep[S]=;
while (!q.empty()) q.pop();
q.push(S);
while (!q.empty())
{
x=q.front();q.pop();
for (int i=h[x];i;i=g[i].nxt)
if (!dep[g[i].y]&&g[i].w)
{
dep[g[i].y]=dep[x]+;
q.push(g[i].y);
if (g[i].y==T) return ;
}
}
return ;
}
int dfs(int x,int flow)
{
if (x==T||(!flow))return flow;
int temp=,js;
for (int i=h[x];i;i=g[i].nxt)
if (dep[g[i].y]==dep[x]+&&g[i].w)
{
js=dfs(g[i].y,min(flow,g[i].w));
if (js)
{
g[i].w-=js;
g[g[i].op].w+=js;
temp+=js;
flow-=js;
if (!flow) return temp;
}
}
if (!temp) dep[x]=;
return temp;
}
int dinic()
{
int ans=;
while (bfs())
ans+=dfs(S,inf);
return ans;
}
}D; void add(int x,int y,int w)
{
g[++tot].x=x;g[tot].y=y;g[tot].w=w;g[tot].nxt=h[x];g[tot].op=tot+;h[x]=tot;
g[++tot].x=y;g[tot].y=x;g[tot].w=;g[tot].nxt=h[y];g[tot].op=tot-;h[y]=tot;
} int n,m,cnt,r,c,TOT,_v[];
int id(int x,int y) {return (x-)*m+y;}
bool not_cir[];int d[]; pas e[];
int e_tot=,e_h[];
void adde(int x,int y)
{
e[++e_tot]=pas{x,y,e_h[x],,,};e_h[x]=e_tot;
d[y]++;
}
void check()
{
while (!q.empty()) q.pop();
for (int i=;i<=n*m;i++) if (!d[i]) q.push(i),not_cir[i]=;
while (!q.empty())
{
int x=q.front();q.pop();
for (int i=e_h[x];i;i=e[i].nxt)
{
d[e[i].y]--;
if (!d[e[i].y]) not_cir[e[i].y]=,q.push(e[i].y);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
S=;T=n*m+;
for (int i=;i<=n;i++) for (int j=;j<=m;j++)
{
scanf("%d",&_v[id(i,j)]);
scanf("%d",&cnt);
for (int k=;k<=cnt;k++)
{
scanf("%d%d",&r,&c);adde(id(i,j),id(r+,c+));
}
if (j!=m) adde(id(i,j+),id(i,j));
}
check();
for (int i=;i<=e_tot;i++) if (not_cir[e[i].x]&¬_cir[e[i].y])add(e[i].y,e[i].x,inf);
for (int i=;i<=n*m;i++) if (not_cir[i]) {if (_v[i]>) add(S,i,_v[i]),TOT+=_v[i];else add(i,T,-_v[i]);}
int ans=;
while (D.bfs())
ans+=D.dfs(S,inf);
printf("%d",TOT-ans);
}
[BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]的更多相关文章
- BZOJ 1565 NOI2009 植物大战僵尸 topo+最小割(最大权闭合子图)
题目链接:https://www.luogu.org/problemnew/show/P2805(bzoj那个实在是有点小小的辣眼睛...我就把洛谷的丢出来吧...) 题意概述:给出一张有向图,这张有 ...
- bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan
bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...
- bzoj1565【NOI2009】植物大战僵尸(最小割)
题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...
- [bzoj1565][NOI2009]植物大战僵尸_网络流_拓扑排序
植物大战僵尸 bzoj1565 题目大意:给你一张网格图,上面种着一些植物.你从网格的最右侧开始进攻.每个植物可以对僵尸提供能量或者消耗僵尸的能量.每个植物可以保护一个特定网格内的植物,如果一个植物被 ...
- LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流
#6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- 洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流
正解:网络流 解题报告: 传送门$QwQ$ 题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价( ...
- BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序
题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...
- BZOJ 1565: [NOI2009]植物大战僵尸(网络流+缩点)
传送门 解题思路 最大权闭合子图.但是要注意一些细节,假如有一堆植物形成一个环,那么这些植物都是无敌的,并且他们保护的植物是无敌的,他们保护的保护的植物是无敌 的.所以要缩点,然后拓扑排序一次判无敌, ...
- BZOJ 1565 [NOI2009]植物大战僵尸 | 网络流
传送门 BZOJ 1565 题解 这道题也是个经典的最大权闭合子图-- 复习一下最大权闭合子图是什么? 就是一个DAG上,每个点有个或正或负的点权,有的点依赖于另外一些点(如果选这个点,则被依赖点必选 ...
随机推荐
- python的os和sys模块
OS模块: 提供对操作系统进行调用的接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目 ...
- VIM之模式
1.模式介绍: 在真正开始使用VIM之前,你必须先了解VIM的模式,否则在 VIM 面前你可能会手足无措.VIM是有模式 编辑器,这意味着 VIM 有多种不同的工作模式,在不同的工作模式下用户相同的操 ...
- windows安装PHP IIS MYSQL
https://www.cnblogs.com/huodong/p/4310425.html
- 博客存档TensorFlow入门一 1.4编程练习
import tensorflow as tf import numpy import matplotlib.pyplot as plt #from sklearn.model_selecti ...
- 批量kill杀死某些会话session的PL/SQL
原文:http://blog.itpub.net/9240380/viewspace-666622/ SQL> declare 2 v_sid v$session.sid%type; --定义如 ...
- list 去重复元素
public static List removeDuplicate(List list){ List listTemp = new ArrayList(); for(int i=0;i<lis ...
- JQuery 同时获取多个标签的指定内容并储存为数组
在网页开发中经常会碰到获取同种类型的 标签 的值得问题,比如下面的两种情况. 当需要批量获取同种标签的指定值时,新人就会碰上一点小麻烦. 比如 id=problem1的demo var list1=$ ...
- windows安装Oracle数据库
我装的版本是Oracle11,64位,直接网上下载即可.安装过程中也出现了一些坑,现在整理了一下. 1.下载的目录和安装的目录最好放到英文目录下,别放到中文或者特殊字符的文件夹中,点击setup.ex ...
- Hadoop集群搭建:用三台云服务器搭建HA集群(过程记录和分享)
该文主要记录了自己用云服务器搭建集群的过程,也分享一些自己遇到的问题和解决方法.里面可能提及一些自己的理解,可能不够准确,希望大家能够指正我,谢谢. 1.什么是HA集群 HA :High Availa ...
- 第一篇 C/C++基本语言类型
总概: { C:面向过程,以过程为中心,以算法为驱动 } { C++:面向对象,以过对象中心,以消息为驱动 个人理解:一切皆对象的思想 } 一 前言总概 1.常量变量 初始化对象与赋值是两个概念 直接 ...