BZOJ1565 植物大战僵尸 题解
题目内容:

题目分析:有选A则必须选B这样的限制条件,可以发现这是最大权闭合子图模型,考虑环的情况,可以推测需要拓扑判环。
代码:
#include<bits/stdc++.h>
using namespace std; struct edge{
int from,to,flow;
}e[]; const int maxn = ,inf = ;
int n,m,num,tmp = ;
int sc[maxn][maxn];
vector <int> at[maxn][maxn];
vector <int> g[maxn*maxn+];
vector <int> ng[maxn*maxn+]; void AddEdge(int from,int to,int w){
e[num++] = (edge){from,to,w}; g[from].push_back(num-);
e[num++] = (edge){to,from,}; g[to].push_back(num-);
} int tp[maxn*maxn+],in[maxn*maxn+];
void topu(){
for(int i=;i<=n;i++) for(int j=;j<=m;j++){
if(j < m)ng[(i-)*m+j+].push_back((i-)*m+j),in[(i-)*m+j]++;
for(int k=;k<at[i][j].size();k++){
int now = at[i][j][k];
ng[(i-)*m+j].push_back(now);
in[now] ++;
}
}
queue <int> q;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)if(!in[(i-)*m+j])q.push((i-)*m+j);
while(!q.empty()){
int k = q.front();q.pop();
tp[k] = ;
for(int i=;i<ng[k].size();i++){
in[ng[k][i]]--;
if(!in[ng[k][i]])q.push(ng[k][i]);
}
}
for(int i=;i<=n*m;i++)ng[i].clear();
for(int i=;i<=n;i++) for(int j=;j<=m;j++){
if(j < m)ng[(i-)*m+j+].push_back((i-)*m+j);
for(int k=;k<at[i][j].size();k++){
int now = at[i][j][k],now2 = (i-)*m+j;
ng[now2].push_back(now);
}
}
for(int i=;i<=n*m;i++) if(tp[i] == ) q.push(i);
while(!q.empty()){
int k = q.front();q.pop();
for(int i=;i<ng[k].size();i++){
if(tp[ng[k][i]]==)continue;
tp[ng[k][i]]=;q.push(ng[k][i]);
}
}
} void build_graph(){
topu();
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(tp[(i-)*m+j]==)continue;
if(sc[i][j] > )AddEdge(,(i-)*m+j,sc[i][j]);
else AddEdge((i-)*m+j,tmp,-sc[i][j]);
for(int k=;k<at[i][j].size();k++){
int now = at[i][j][k];
if(tp[now]==)continue;
AddEdge(now,(i-)*m+j,inf);
}
if(j < m && tp[(i-)*m+j+])AddEdge((i-)*m+j,(i-)*m+j+,inf);
}
}
} void read(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
for(int j=,x;j<=m;j++){
scanf("%d%d",&sc[i][j],&x);
for(int k=,p1,q1;k<=x;k++) {
scanf("%d%d",&p1,&q1);p1++;q1++;
at[i][j].push_back((p1-)*m+q1);
}
}
}
build_graph();
} int dis[maxn*maxn+],cur[maxn*maxn+];
int BFS(){
queue <int> q;
memset(dis,-,sizeof(dis));
q.push(); dis[] = ;
while(!q.empty()){
int k = q.front();q.pop();
for(int i=;i<g[k].size();i++){
edge nxt = e[g[k][i]];
if(nxt.flow > && (dis[nxt.to]==-)){
dis[nxt.to] = dis[k]+; q.push(nxt.to);
}
}
}
return dis[tmp];
} int dfs(int x,int a){
if(x == tmp || a == ) return a;
int flow = ,f;
for(int &i=cur[x];i<g[x].size();i++){
edge &eg = e[g[x][i]];
if(dis[eg.to] > dis[x] && ((f = dfs(eg.to,min(eg.flow,a)))>)){
eg.flow -= f;
e[g[x][i]^].flow += f;
a -= f; flow += f;
if(a == ) break;
}
}
return flow;
} void work(){
int flow;
while(BFS()!=-){
memset(cur,,sizeof(cur));
flow = dfs(,inf);
}
int ans = ;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(dis[(i-)*m+j]!=-) ans += sc[i][j];
}
}
printf("%d",ans);
} int main(){
read();
work();
return ;
}
BZOJ1565 植物大战僵尸 题解的更多相关文章
- BZOJ1565:[NOI2009]植物大战僵尸——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1565 https://www.luogu.org/problemnew/show/P2805 Pla ...
- 【BZOJ1565】【NOI2009】植物大战僵尸(网络流)
[BZOJ1565][NOI2009]植物大战僵尸(网络流) 题面 BZOJ 洛谷 题解 做了这么多神仙题,终于有一道能够凭借自己智商能够想出来的题目了.... 好感动. 这就是一个比较裸的最小割模型 ...
- [bzoj1565][NOI2009]植物大战僵尸_网络流_拓扑排序
植物大战僵尸 bzoj1565 题目大意:给你一张网格图,上面种着一些植物.你从网格的最右侧开始进攻.每个植物可以对僵尸提供能量或者消耗僵尸的能量.每个植物可以保护一个特定网格内的植物,如果一个植物被 ...
- bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan
bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...
- 【BZOJ-1565】植物大战僵尸 拓扑排序 + 最小割
1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1972 Solved: 917[Submit][Statu ...
- Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序
题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:p ...
- tyvj P1135 - 植物大战僵尸 最大权闭合图
P1135 - 植物大战僵尸 From ytt Normal (OI)总时限:10s 内存限制:128MB 代码长度限制:64KB 背景 Background 虽然这么多天了,,虽然 ...
- BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流
题意: 植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: (1)价值: (2)保护集合,也就是这个植物可以保护矩阵中的某些格子. 现在你是僵尸,你每次只能从(i,m) 格子 ...
- 植物大战僵尸中文第二版和年度版 游戏分析及delphi源码
00413184 |. E8 77E30100 |CALL PlantsVs.00431500 ; 地上的物品00413189 |. 8D7424 10 ...
随机推荐
- 接口-以PHP为例
<?php //使用程序模拟现实情况 //使用规范(方法/属性) interface iUSB { public function start(); public function stop() ...
- alter 和 update的区别?
alter用来增加或者减少列,alter stuednt add name vachar2(30): update用来更改表中的数据:update student set sutudent.name ...
- 记录一个 spring cloud 配置中心的坑,命令行端口参数无效,被覆盖,编码集问题无法读取文件等.
spring cloud 配置中心 结合GIT , 可以运行时更新配置文件.发送指令让应用重新读取配置文件. 最近在测试服务器实现了一套,结果CPU 实用率暴增,使用docker compose启动 ...
- 妙用ES6解构和扩展运算符让你的代码更优雅
http://www.cnblogs.com/chrischjh/p/4848934.html
- shell脚本基础1 概述及变量
shell概述:在linux内核与用户之间的解释器程序通常指/bin/bash负责指向内核翻译及传达用户/程序指令相当于操作系统的"外壳" shell的使用方式:交互式--命令行: ...
- 修改android 开机画面
对于使用安卓手机的人来说,能够自由定制手机的各种界面是每个用户之所以喜欢安卓系统的最根本的缘由,比如手机的开机界面中的bootanimation.zip文件.本文就如何修改开机界面,做一个简单的流程介 ...
- Windows Subsystem for Linux (WSL)挂载移动硬盘U盘
WSL想通过移动硬盘处理一些数据,结果进去了无法发现移动硬盘,于是搜了好久也没有一个正确的解决办法,终于找到一个,现在贡献出来与大家共享. WSL比起linux挂载硬盘简单一些.而且windows本身 ...
- RVDS4.0 + JLINK 调试 cortex-A9
1.RVDS4.0的安装与破解 参看http://blog.csdn.net/cp1300/article/details/7772645这位大神的帖子吧,写的很详细. 2.JLINK驱动的安装 这里 ...
- linux驱动---字符设备的注册register_chrdev说起
首先我们在注册函数里面调用了register_chrdev(MEM_MAJOR,"mem",&memory_fops),向内核注册了一个字符设备. 第一个参数是主设备号,0 ...
- 安装sphinx和coreseek
sphinx简介 Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎.意图为其他应用提供高速.低空间占用.高结果 相关度的全文搜索功能.Sphinx可以非常容易的与SQL数 ...