题目大意

​  给你一个\(n\times m\)的地图,每个格子上都有一颗植物,有的植物能保护其他植物。僵尸从右往左进攻,每吃掉一颗植物就可以得到\(a_{i,j}\)的收益(\(a_{i,j}\)可以是负数)。求僵尸的最大收益

​  \(1\leq n\leq20,1\leq m\leq30\)

题解

​  这种一个东西可以保护另一个东西而且数据范围那么小的题目显然是最大权闭合子图。

​  僵尸从右往左进攻,所以一棵植物可以保护它左边的植物。

​  如果保护关系形成一个环,就都不能选。

​  直接套模板即可。

​  可能需要一些优化

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
struct list
{
int v[1000010];
int w[1000010];
int t[1000010];
int h[1010];
int n;
list()
{
memset(h,0,sizeof h);
n=0;
}
void add(int x,int y,int z)
{
n++;
v[n]=y;
w[n]=z;
t[n]=h[x];
h[x]=n;
}
};
list l,l2;
void add(int x,int y,int z)
{
l.add(x,y,z);
l.add(y,x,0);
}
int n,m;
int w[110][110];
int gx[1010];
int gy[1010];
int id(int x,int y)
{
return (x-1)*m+y;
}
int vis[1010];
int b[1010];
void dfs(int x)
{
vis[x]=1;
int i;
for(i=l2.h[x];i;i=l2.t[i])
{
if(!vis[l2.v[i]])
dfs(l2.v[i]);
if(b[l2.v[i]]||vis[l2.v[i]]==1)
{
// w[gx[x]][gy[x]]=-10000000;
b[x]=1;
}
}
vis[x]=2;
}
int d[1010];
int S,T;
int c[30][40][30][40];
int bfs()
{
memset(d,-1,sizeof d);
queue<int> q;
q.push(S);
d[S]=0;
int x,i;
while(!q.empty())
{
x=q.front();
q.pop();
for(i=l.h[x];i;i=l.t[i])
if(l.w[i]&&d[l.v[i]]==-1)
{
d[l.v[i]]=d[x]+1;
if(l.v[i]==T)
return 1;
q.push(l.v[i]);
}
}
return 0;
}
int op(int x)
{
return ((x-1)^1)+1;
}
int dfs(int x,int flow)
{
if(x==T)
return flow;
int c,s=0,i;
for(i=l.h[x];i;i=l.t[i])
if(l.w[i]&&d[l.v[i]]==d[x]+1)
{
c=dfs(l.v[i],min(flow,l.w[i]));
s+=c;
flow-=c;
l.w[i]-=c;
l.w[op(i)]+=c;
if(!flow)
break;
}
if(flow)
d[x]=-1;
return s;
}
int main()
{
memset(b,0,sizeof b);
memset(c,0,sizeof c);
// freopen("bzoj1565.in","r",stdin);
// freopen("bzoj1565.out","w",stdout);
scanf("%d%d",&n,&m);
S=n*m+1;
T=S+1;
int sum=0;
int i,j,k,o,x,y,u;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&w[i][j]);
gx[id(i,j)]=i;
gy[id(i,j)]=j;
scanf("%d",&u);
for(k=1;k<=u;k++)
{
scanf("%d%d",&x,&y);
x++;
y++;
c[i][j][x][y]=1;
}
if(j>1)
c[i][j][i][j-1]=1;
for(x=1;x<=n;x++)
for(y=1;y<=m;y++)
if(c[i][j][x][y])
l2.add(id(x,y),id(i,j),0);
}
memset(vis,0,sizeof vis);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(!vis[id(i,j)])
dfs(id(i,j));
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(!b[id(i,j)])
{
if(w[i][j]>0)
{
sum+=w[i][j];
add(S,id(i,j),w[i][j]);
}
else
add(id(i,j),T,-w[i][j]);
for(x=1;x<=n;x++)
for(y=1;y<=m;y++)
if(c[i][j][x][y])
if(!b[id(x,y)])
add(id(x,y),id(i,j),0x7fffffff);
}
int ans=0;
while(bfs())
ans+=dfs(S,0x7fffffff);
printf("%d\n",sum-ans);
return 0;
}

【BZOJ1565】【NOI2009】植物大战僵尸 网络流 最大权闭合子图的更多相关文章

  1. BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】

    题目 输入格式 输出格式 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. 输入样例 3 2 10 0 20 0 -10 0 -5 1 0 0 100 ...

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

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

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

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

  4. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  5. BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序

    题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...

  6. [bzoj1565][NOI2009]植物大战僵尸_网络流_拓扑排序

    植物大战僵尸 bzoj1565 题目大意:给你一张网格图,上面种着一些植物.你从网格的最右侧开始进攻.每个植物可以对僵尸提供能量或者消耗僵尸的能量.每个植物可以保护一个特定网格内的植物,如果一个植物被 ...

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

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

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

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

  9. BZOJ 1565 植物大战僵尸(最大权闭合图)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1565 题意:植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: ...

随机推荐

  1. AtCoder Beginner Contest 053

    D - Card Eater Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement Snuke h ...

  2. 15-分析Ajax请求并抓取今日头条街拍美图

    流程框架: 抓取索引页内容:利用requests请求目标站点,得到索引网页HTML代码,返回结果. 抓取详情页内容:解析返回结果,得到详情页的链接,并进一步抓取详情页的信息. 下载图片与保存数据库:将 ...

  3. Python_函数的初识、函数的返回值、函数的参数

    1.函数的初识 def关键字 空格 函数名(与变量名命名规则相同):英文冒号 函数体 执行函数:函数名+() 函数是以功能为导向的. def login(): pass def register(): ...

  4. java的数据类型:基本数据类型和引用数据类型

    Java数据类型的基本概念 数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式. 开始接触每种语言的时候,都会存在对数据类型的认识,有复杂的,有复杂的,各 ...

  5. 50分钟学会Laravel 50个小技巧(基于laravel5.2,仅供参考)

    转载请注明:转载自 Yuansir-web菜鸟 | LAMP学习笔记 本文链接地址: 50分钟学会Laravel 50个小技巧 原文链接:< 50 Laravel Tricks in 50 Mi ...

  6. 【Spring】——声明式事务配置详解

    项目中用到了spring的事务: @Transactional(rollbackFor = Exception.class, transactionManager = "zebraTrans ...

  7. Spring注解 系列之Spring常用注解总结

    参考:Spring系列之Spring常用注解总结 (1) Resource 默认是byName的方式进行bean配置,@AutoWired默认是按照byType的方式进行装配bean的:(2)Comp ...

  8. 老男孩python学习自修第二十一天【socket】

    1. 使用python编写一个静态的web服务器,能够处理静态页面的http请求 原理: a. 使用socket进行服务端和浏览器之间的通信 b. 使用多线程处理多个客户端浏览器的请求 c. 解析用户 ...

  9. 个人用的感觉比较舒服的 idea 插件,不定时更新

    1.mybatis plugin 用的最舒服的 idea 上的 plugin 之一,快速跳转 dao 的映射的 xml 文件,生成配置文件.语法提示等 不过这个收费,,具体步骤百度吧 2.Rainbo ...

  10. 利用H5 FormData 实现表单中多图上传(可带其他如String类型数据)

    本篇的具体思路来源于右侧网址:http://blog.csdn.net/qq_19551571/article/details/49977983 本篇代码有所修改,请具体区分. 本篇使用的是 form ...