# 【NOI2009】植物大战僵尸

## 题解

$G'(V',E')$$G(V,E)$的闭合子图。
$\begin{cases} V' \in V, E' \in E\\ \forall (u,v) \in E, u \in V' \& \& v \in V' \end{cases}$

## 代码

#include <bits/stdc++.h>

const int maxid = 970;
const int maxn = 25;
const int maxm = 35;
const int inf = 0x3f3f3f3f;
using std::min;

template<class t> inline void read(t& res) {
res = 0;  char ch = getchar();  bool neg = 0;
while(!isdigit(ch))
neg |= ch == '-', ch = getchar();
while(isdigit(ch))
res = (res << 1) + (res << 3) + (ch & 15), ch = getchar();
if(neg)
res = -res;
}
inline int id(int a,int b) { return a * 31 + b; }

int n, m, i, j, k, S, st, ed, cnte = 1;
int dep[maxid], sco[maxid];
int in[maxid];  std::vector<int> rev[maxid];
int hd[maxid], cur[maxid], ver[maxid * maxid << 1], nxt[maxid * maxid << 1], wei[maxid * maxid << 1];
bool vis[maxid];
inline void adde(int u,int v,int w) {
ver[++cnte] = v;  wei[cnte] = w;  nxt[cnte] = hd[u];  hd[u] = cnte;
ver[++cnte] = u;  wei[cnte] = 0;  nxt[cnte] = hd[v];  hd[v] = cnte;
}
std::queue<int> q;
inline void tpsort() {
for(int i = 1;i <= n;i++) {
for(int j = 1, I;j <= m;j++) {
I = id(i,j);
if(!in[I])
vis[I] = 1, q.push(I);
}
}
while(!q.empty()) {
int u = q.front();  q.pop();
for(int i = 0, le = rev[u].size();i < le;i++) {
int v = rev[u][i];
in[v]--;
if(!in[v] && !vis[v])
vis[v] = 1, q.push(v);
}
}
}

inline bool bfs() {
std::queue<int> q;
memset(dep,0,sizeof(dep));
dep[st] = 1;  q.push(st);
while(!q.empty()) {
int u = q.front();  q.pop();
for(int i = hd[u];~i;i = nxt[i]) {
int v = ver[i];  int w = wei[i];
if(!dep[v] && w) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[ed];
}
int dfs(int u,int flow) {
if(u == ed)
return flow;
int dec = flow;
for(int& i = cur[u];~i && dec;i = nxt[i]) {
int v = ver[i];  int w = wei[i];
if(dep[u] + 1 == dep[v] && w) {
int tmp = dfs(v,min(w,dec));
dec -= tmp;
wei[i] -= tmp;
wei[i ^ 1] += tmp;
}
}
return flow - dec;
}
inline void dinic() {
while(bfs()) {
memcpy(cur,hd,sizeof(hd));
while(int flow = dfs(st,inf))
S -= flow;
}
return;
}

int main() {
memset(hd,-1,sizeof(hd));
for(int i = 1;i <= n;i++) {
for(int j = 1, I;j <= m;j++) {
for(int k = 1, r, c, J;k <= w;k++) {
rev[I].push_back(J);
in[J]++;
}
if(j < m) {
int J = id(i,j + 1);
rev[J].push_back(I);
in[I]++;
}
}
}
tpsort();
st = maxid - 1, ed = maxid - 2;
S = 0;
for(int i = 1;i <= n;i++) {
for(int j = 1, I;j <= m;j++) {
I = id(i,j);
if(!vis[I])
continue;
if(sco[I] >= 0)
else
for(int k = 0, le = rev[I].size();k < le;k++) {
int v = rev[I][k];
if(vis[v])