bzoj 1565 [NOI2009]植物大战僵尸 解题报告
1565: [NOI2009]植物大战僵尸
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 2161 Solved: 1000
[Submit][Status][Discuss]
Description

Input

Output
Sample Input
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
Sample Output
HINT
在样例中, 植物P1,1可以攻击位置(0,0), P2, 0可以攻击位置(2,1)。
一个方案为,首先进攻P1,1, P0,1,此时可以攻击P0,0 。共得到能源收益为(-5)+20+10 = 25。注意, 位置(2,1)被植物P2,0保护,所以无法攻击第2行中的任何植物。
【大致数据规模】
约20%的数据满足1 ≤ N, M ≤ 5;
约40%的数据满足1 ≤ N, M ≤ 10;
约100%的数据满足1 ≤ N ≤ 20,1 ≤ M ≤ 30,-10000 ≤ Score ≤ 10000 。
Source
————————————————我是分割线——————————————————————————
好题啊好题
这题折腾了三天,差点没吐出血来。
先拓扑排序求环,把环删掉。
之后重建图求最大权闭合子图,把一个植物向保护它的植物连边,跑一遍网络流即可。
第一次只过了4个点。不明所以。
换方法重写了拓扑,在网络流中加限制乱搞。
终于90,但第九个点一直RE,最后发现数组开小了。这题最多600个点,但边数组一直开到800005才A了。TAT~
/*
Problem: bzoj 1565 [NOI2009]植物大战僵尸
OJ: bzoj
User: S.B.S.
Time: 264 MS
Memory: 13884 KB
Length: 6934 B
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<iomanip>
#include<cassert>
#include<climits>
#include<functional>
#include<bitset>
#include<vector>
#include<list>
#define F(i,j,k) for(int i=j;i<=k;++i)
#define M(a,b) memset(a,b,sizeof(a))
#define FF(i,j,k) for(int i=j;i>=k;i--)
#define inf 0x3f3f3f3f
#define maxm 1001
#define mod 998244353
//#define LOCAL
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m;
int mp[];
struct EDGE
{
int from;
int to;
int value;
int next;
}e[];
int head[];
int v[],in[],out[];
int tot=;
inline void addedge(int u,int v,int w)
{
e[++tot].from=u;
e[tot].to=v;
e[tot].value=w;
e[tot].next=head[u];
head[u]=tot;
// tot++;
}
//bool kan[2000][2000];
int ans=;
//inline int at(int x,int y)
//{
// return m*x+y+1;
//}
//int stk[4001],top=0;
//inline void topsort()
//{
// int temp[4001];M(temp,0);
// F(i,1,m*n) temp[i]=in[i];
// F(i,1,m*n){
// if(in[i]==0){
// stk[top]=i;
//// cout<<i<<"********"<<endl;
// top++;
// }
// }
//// cout<<top<<": "<<endl;
//// F(i,0,top-1) cout<<stk[i]<<" ";cout<<endl;
// while(top!=0){
// top--;int u=stk[top];
// for(int i=head[u];i!=-1;i=e[i].next)
// {
// in[e[i].to]--;
// if(in[e[i].to]==0){
// stk[top]=e[i].to;
// top++;
// }
// }
// }
// F(i,1,m*n){
// if(in[i]!=0){
// stk[top]=i;
// top++;
// }
// }
// while(top!=0){
// top--;int u=stk[top];
// temp[u]=-1;out[u]=-1;
// v[u]=0;
// }
// F(i,1,m*n) in[i]=temp[i];
// return;
//}
inline void add(int u,int v,int w)
{
addedge(u,v,w);
addedge(v,u,);
++in[u];
return;
}
int map[];
int S,T;
bool ok()
{
F(i,S,T) if(map[i]!=-) map[i]=-;
int que[];
int hd=,tl=;
que[tl++]=S;
map[S]=;
while (hd<tl){
int u=que[hd++];
for(int i=head[u];i;i=e[i].next)
{
if(map[e[i].to]==-&&e[i].value)
{
map[e[i].to]=map[u]+;
que[tl++]=e[i].to;
}
}
}
// if (map[T]!=-1) return true;
// else return false;
return map[T]>;
}
int cur[];
int zeng(int k,int now)
{
if (k==T) return now;
int r=;
for (int i=cur[k];i&&now>r;i=e[i].next)
{
if (map[k]+==map[e[i].to]&&e[i].value)
{
int t=zeng(e[i].to,min(now-r,e[i].value));
e[i].value-=t;e[i^].value+=t;r+=t;
if(e[i].value) cur[k]=i;//***
// cout<<e[i].from<<" ---> "<<e[i].to<<" $ "<<t<<endl;
}
}
if (!r) map[k]=-;
return r;
}
int dinic()
{
int r=,t;
M(cur,);
while (ok()){
for(int i=S;i<=T;++i) cur[i]=head[i];
r+=zeng(S,inf);
// while(t=zeng(S,inf)) r+=t;
}
return r;
}
//pair<int,int> kk[4001];
//int cur;
int main()
{
std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
#ifdef LOCAL
freopen("111.in","r",stdin);
freopen("data.out","w",stdout);
#endif
cin>>n>>m;
S=;T=m*n+;
M(mp,);M(head,);
// F(i,0,n-1)F(j,0,m-1){
// int x,y;
// cin>>x>>y;
// mp[i][j]=x;
// v[at(i,j)]=x;
// in[at(i,j)]++;
// if(j==m-1) in[at(i,j)]--;
// if(j!=0) add(at(i,j),at(i,j-1),v[at(i-1,j)]);
// if(y==0) continue;
//// **********************************************
// F(k,1,y){
// int a,b;
// cin>>a>>b;
// kk[cur].first=at(i,j);
// kk[cur].second=at(a,b);
// cur++;
// in[at(a,b)]++;
// addedge(at(i,j),at(a,b),0);
//// cout<<at(i,j)<<" "<<at(a,b)<<" &&&&&"<<endl;
// }
// }
// F(i,1,m*n) cout<<in[i]<<" ";cout<<endl;
// cout<<"/*****************************"<<endl;
// F(i,1,tot) cout<<e[i].from<<" ---> "<<e[i].to<<" $ "<<e[i].value<<endl;
// cout<<"*****************************/"<<endl;
F(i,,n*m){
int temp;
cin>>mp[i];
if(mp[i]>) add(S,i,mp[i]);
else add(i,T,-mp[i]);
cin>>temp;
while(temp--){
int x,y;
cin>>x>>y;
add(x*m+y+,i,inf);
}
if(i%m) add(i,i+,inf);
}
// topsort();
// cout<<"))))))"<<endl;
// F(i,1,m*n) if(in[i]==-1) cout<<i<<" ";cout<<"((((("<<endl;
// M(e,0);M(head,-1);tot=0;
int q[];M(q,);
int cur1=,cur2=;
for(int i=S;i<=T;++i){
if(!in[i]) q[cur2++]=i;
map[i]=-;
}
int sum=;
while(cur1<cur2){
int cnt=q[cur1++];map[cnt]=;
if(mp[cnt]>) sum+=mp[cnt];
for(int i=head[cnt];i;i=e[i].next)
{
if(i&) if(!--in[e[i].to]) q[cur2++]=e[i].to;
}
}
// F(i,1,m*n) cout<<in[i]<<" ";cout<<endl;
// cout<<"v: "<<endl;
// F(i,1,m*n) cout<<v[i]<<" ";cout<<endl;
// F(i,0,n-1)F(j,0,m-1){
// if(in[at(i,j)]==-1) continue;
//// cout<<at(i,j)<<" : "<<in[at(i,j)]<<"@ "<<endl;
// if(j!=0&&in[at(i,j-1)]!=-1) add(at(i,j-1),at(i,j),inf);
// if(v[at(i,j)]==0) continue;
// if(v[at(i,j)]>0) add(31,at(i,j),v[at(i,j)]),sum+=v[at(i,j)];
// else add(at(i,j),32,-v[at(i,j)]);
// }
// while(cur!=0){
// cur--;
// if(in[kk[cur].first]==-1||in[kk[cur].second]==-1) continue;
// int u=kk[cur].first;
// int v=kk[cur].second;
// add(v,u,inf);
// }
// cout<<"/*****************************"<<endl;
// F(i,1,tot) cout<<e[i].from<<" ---> "<<e[i].to<<" $ "<<e[i].value<<endl;
// cout<<"*****************************/"<<endl;
// cout<<sum<<endl;
cout<<sum-dinic()<<endl;
return ;
}
/*
3 2
10 0
20 0
-10 0
-5 1 0 0
100 1 2 1
100 0
*/
植物大战僵尸
bzoj 1565 [NOI2009]植物大战僵尸 解题报告的更多相关文章
- BZOJ 1565: [NOI2009]植物大战僵尸( 最小割 )
先拓扑排序搞出合法的, 然后就是最大权闭合图模型了.... --------------------------------------------------------------------- ...
- Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序
题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★ 输入文件:pvz.in 输出文件:p ...
- 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告
P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...
- BZOJ 1565 [NOI2009]植物大战僵尸 | 网络流
传送门 BZOJ 1565 题解 这道题也是个经典的最大权闭合子图-- 复习一下最大权闭合子图是什么? 就是一个DAG上,每个点有个或正或负的点权,有的点依赖于另外一些点(如果选这个点,则被依赖点必选 ...
- BZOJ 1565 NOI2009 植物大战僵尸 topo+最小割(最大权闭合子图)
题目链接:https://www.luogu.org/problemnew/show/P2805(bzoj那个实在是有点小小的辣眼睛...我就把洛谷的丢出来吧...) 题意概述:给出一张有向图,这张有 ...
- BZOJ 1565: [NOI2009]植物大战僵尸(网络流+缩点)
传送门 解题思路 最大权闭合子图.但是要注意一些细节,假如有一堆植物形成一个环,那么这些植物都是无敌的,并且他们保护的植物是无敌的,他们保护的保护的植物是无敌 的.所以要缩点,然后拓扑排序一次判无敌, ...
- bzoj 1565 [NOI2009]植物大战僵尸【tarjan+最大权闭合子图】
一上来以为是裸的最大权闭合子图,上来就dinic -然后没过样例.不得不说样例还是非常良心的给了一个强连通分量,要不然就WA的生活不能自理了 然后注意到有一种特殊情况:每个植物向他保护的植物连边(包括 ...
- 1565: [NOI2009]植物大战僵尸 - BZOJ
Description Input Output仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0.Sample Input3 210 020 0-10 0 ...
- BZOJ 1565: [NOI2009]植物大战僵尸
1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2317 Solved: 1071[Submit][Stat ...
随机推荐
- 【POJ】1704.Georgia and Bob
题解 感觉挺神奇的 我们把石子从后往前相邻的两个两两配对,这样他们之间的空格就相当于一堆石子 而配对后左边棋子移动,右边棋子也一定可以跟上取 转化成简单的nim游戏,最后只要看转化出的这(N - 1) ...
- URLconf+MTV:Django眼中的MVC
MVC是众所周知的模式,即:将应用程序分解成三个组成部分:model(模型),view(视图),和 controller(控制 器).其中: M 管理应用程序的状态(通常存储 ...
- vim中E121:无法打开并写入文件解决办法
1.使用命令 :w !sudo tee % 保存即可. 其中: 冒号(:)表示我们处于vim的退出模式: 感叹号(!)表示我们正在运行shell命令: sudo和tee都是shell命令: %表示从 ...
- c/c++--strlen()小问题
int x = 2; char * str = "abcd"; int y = (x - strlen(str)) / 3; printf("%d\n", y) ...
- <泛> 多路快排
今天写一个多路快排函数模板,与STL容器兼容的. 我们默认为升序排序 因为,STL容器均为逾尾容器,所以我们这里采用的参数也是逾尾的参数 一.二路快排 基本思路 给你一个序列,先选择一个数作为基数,我 ...
- JS Function Arguments
Function arguments在ECMAScript中的行为并不像其他大多数语言中的函数参数. 在ECMAScript中,function 并不关心有多少个参数传入函数中,也不关心传入参数的数据 ...
- 7.4 (java学习笔记)网络编程之TCP
一.TCP 1.1 TCP(Transmission Control Protocol 传输控制协议),是一种面向连接的,安全的传输协议,但效率相比于UDP而言比较低. TCP传输时需要确保先建立连接 ...
- 深入理解RESTful Web Services
RESTful的软件架构已经多火不用多说,和MVC架构一样,很多网站服务(Web Services)都遵循RESTful设计模式,那么到底什么是RESTful Web Services呢?设计一个RE ...
- Android之基于HTTP协议的通信详解
Android系统中本身是有下载机制的,比如浏览器使用的DownloadManager.可遗憾的是,DownloadManager只提供给浏览器使用,一般的应用程序没法调用它. 另外,如果下载调用频繁 ...
- Codeforces Round #294 (Div. 2)D - A and B and Interesting Substrings 字符串
D. A and B and Interesting Substrings time limit per test 2 seconds memory limit per test 256 megaby ...