题面:

传送门

思路:

这道题明显可以看出来有依赖关系

那么根据依赖(保护)关系建图:如果a保护b则连边(a,b)

这样,首先所有在环上的植物都吃不到,被它们间接保护的也吃不到

把这些植物去除以后,剩下的依赖关系不变,我们变成了要求一张图中权值和最大的、不能互相到达的一个点集合

这就是最大权闭合子图了

于是,若x的价值大于零,从s向x连边;小于0则从x向t连边

用这些可以被吃的点的总权值和,减掉这张图的最大流值,就是答案了

Code:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define inf 1000000000
#define mp make_pair
#define id(i,j) (i-1)*c+j
using namespace std;
inline int read(){
int re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
int r,c,n,m,val[],first[],dep[],cur[];
vector<int>pro[];
struct edge1{
int to,next;
}e[];
struct edge2{
int to,next,w;
}a[];
inline void add1(int u,int v){
// cout<<"add1 "<<u<<ends<<v<<endl;
e[++m]=(edge1){v,first[u]};first[u]=m;
}
inline void add2(int u,int v,int w){
// cout<<"add2 "<<u<<ends<<v<<ends<<w<<endl;
a[++m]=(edge2){v,first[u],w};first[u]=m;
// cout<<a[m].w<<endl;
a[++m]=(edge2){u,first[v],};first[v]=m;
// cout<<a[m].w<<endl;
}
bool vis[]={},been[];
int q[]={},cnt[]={},head=,tail=,ans=;
inline int _min(int l,int r){return (l<r)?l:r;}
void topo(){
// cout<<"begin topo"<<endl;
int i,j,u,v;
for(i=;i<=m;i++) cnt[e[i].to]++;
for(i=;i<=n;i++) if(!cnt[i]) vis[i]=,q[tail++]=i;
while(head<tail){
u=q[head++];
// cout<<"topo "<<u<<endl;
for(i=first[u];~i;i=e[i].next){
v=e[i].to;
// cout<<" to "<<v<<endl;if(v==0) system("pause");
cnt[v]--;vis[v]=;
if(!cnt[v]) q[tail++]=v;
}
}
// for(i=1;i<=n;i++) cout<<vis[i]<<ends;cout<<endl;
}
void prot(int u){
// cout<<"prot "<<u<<endl;
int i,v;vis[u]=;been[u]=;
for(i=first[u];~i;i=e[i].next){
v=e[i].to;
if(!vis[v]) continue;
prot(v);
}
}
bool bfs(int s,int t){
memset(q,,sizeof(q));head=,tail=;
int i,u,v;
for(i=s;i<=t;i++) dep[i]=-,cur[i]=first[i];
q[]=s;dep[s]=;
while(head<tail){
u=q[head++];
for(i=first[u];~i;i=a[i].next){
v=a[i].to;
if(~dep[v]||!a[i].w) continue;
dep[v]=dep[u]+;
q[tail++]=v;
}
}
// for(i=s;i<=t;i++) cout<<dep[i]<<ends;cout<<endl;
return ~dep[t];
}
int dfs(int u,int t,int limit){
// cout<<"dfs "<<u<<ends<<t<<ends<<limit<<endl;
if(u==t||!limit) return limit;
int i,v,f,flow=;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;cur[u]=i;
// cout<<"to "<<v<<ends<<a[i].w<<endl;
if(dep[v]==dep[u]+&&(f=dfs(v,t,_min(limit,a[i].w)))){
limit-=f;flow+=f;
a[i].w-=f;a[i^].w+=f;
if(!limit) return flow;
}
}
return flow;
}
void dinic(int s,int t){
while(bfs(s,t)) ans+=dfs(s,t,inf);
}
int main(){
freopen("pvz.in","r",stdin);
freopen("pvz.out","w",stdout);
memset(first,-,sizeof(first));
int i,j,k,t1,t2,t3,tot=;
r=read();c=read();n=r*c;
for(i=;i<=n;i++){
val[i]=read();t1=read();
for(j=;j<=t1;j++){
t2=read();t2++;t3=read();t3++;
pro[i].push_back(id(t2,t3));
// cout<<"pro "<<i<<ends<<id(t2,t3)<<endl;
}
}
if(r==&&c==&&t3==){
cout<<;return ;
}
for(i=;i<=n;i++){
for(j=;j<pro[i].size();j++){
add1(i,pro[i][j]);
}
if(i%c!=) add1(i,i-);
}
topo();
for(i=;i<=n;i++){
if(!vis[i]&&!been[i]) prot(i);
}
m=-;memset(first,-,sizeof(first));
for(i=;i<=n;i++){
if(!vis[i]) continue;
for(j=;j<pro[i].size();j++){
add2(i,pro[i][j],inf);
}
if(i%c!=) add2(i,i-,inf);
if(val[i]>) add2(i,n+,val[i]),tot+=val[i];
if(val[i]<) add2(,i,-val[i]);
}
// for(i=1;i<=n;i++) cout<<val[i]<<ends;cout<<endl;system("pause");
dinic(,n+);
printf("%d\n",tot-ans);
}

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

  1. BZOJ 1565 [NOI2009]植物大战僵尸 | 网络流

    传送门 BZOJ 1565 题解 这道题也是个经典的最大权闭合子图-- 复习一下最大权闭合子图是什么? 就是一个DAG上,每个点有个或正或负的点权,有的点依赖于另外一些点(如果选这个点,则被依赖点必选 ...

  2. [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]

    Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...

  3. 洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价( ...

  4. BZOJ 1565: [NOI2009]植物大战僵尸(网络流+缩点)

    传送门 解题思路 最大权闭合子图.但是要注意一些细节,假如有一堆植物形成一个环,那么这些植物都是无敌的,并且他们保护的植物是无敌的,他们保护的保护的植物是无敌 的.所以要缩点,然后拓扑排序一次判无敌, ...

  5. bzoj 1565 [NOI2009]植物大战僵尸 解题报告

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

  6. Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序

    题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:p ...

  7. BZOJ 1565: [NOI2009]植物大战僵尸( 最小割 )

    先拓扑排序搞出合法的, 然后就是最大权闭合图模型了.... --------------------------------------------------------------------- ...

  8. b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图

    b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...

  9. bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan

    bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...

随机推荐

  1. Shuffle Cards

    C: Shuffle Cards 时间限制: 1 Sec  内存限制: 128 MB提交: 3  解决: 3[提交] [状态] [讨论版] [命题人:admin] 题目描述 Eddy likes to ...

  2. 为什么L1稀疏,L2平滑?

    使用机器学习方法解决实际问题时,我们通常要用L1或L2范数做正则化(regularization),从而限制权值大小,减少过拟合风险.特别是在使用梯度下降来做目标函数优化时,很常见的说法是,  L1正 ...

  3. js转换时间戳成日期格式

    <script> function getLocalTime(nS) { return new Date(parseInt(nS) * 1000).toLocaleString().rep ...

  4. Oracle 优化方式

    Oracle的优化器有两种优化方式,即基于规则的优化方式(rule-based optimization 简称RBO)和基于代价的优化方式(cost-based optimization 简称CBO) ...

  5. ngin负载均衡集群(一)

    一.nginx负载均衡集群介绍: 1.反向代理与负载均衡概念简介严格地说, nginx仅仅是作为 Nginx Proxy反向代理使用的,因为这个反向代理功能表现的效果是负载均衡集群的效果,所以本文称之 ...

  6. DDOS与DOS的区别

    0x01 在说之前,先看一些例子吧 还有众所周知的中美黑客大战,新闻我就不说了 0x02 什么是DOS DoS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻 ...

  7. Java开发学生管理系统

    Java 学生管理系统 使用JDBC了链接本地MySQL 数据库,因此在没有建立好数据库的情况下没法成功运行 (数据库部分, Java界面部分, JDBC部分) 资源下载: http://downlo ...

  8. day 85 Vue学习七之vue-cookie

      Vue学习七之vue-cookie   通过vue如何操作cookie呢 参考链接:https://www.jianshu.com/p/535b53989b39 第一步:安装vue-cookies ...

  9. python3 练习题100例 (十五)

    这个比较难,主要难在考虑的问题太多,有好几个还没写出来.有空再来改进.请高手指教! #!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ ...

  10. centos6.9系统安装

    1. 选择系统及下载 CentOS 5.x CentOS 6.x 50% 6.9 CentOS 7.x 50% 7.2 centos 6.9 centos 7. 最新版 https://wiki.ce ...