好久没写博客了

题目

题目在这里

思路&做法

没什么好说的

应该很容易看出是 最大闭合子图 吧?

不过要注意一下的是,这题 可能有植物是不可能被击溃的 , 所以要先跑一遍 拓扑排序 把这些点排除掉

代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm> using namespace std; const int N = 810, M = 500010; const int INF = 0x7F7F7F7F; int n, m; int val[40][40];
vector< pair<int, int> > vec[40][40]; bool vis[N]; //vis为0的点就是不可能击溃的点 struct edge
{ int from, to, flow, cap;
edge() { }
edge(int _1, int _2, int _3, int _4) : from(_1), to(_2), flow(_3), cap(_4) { }
}; struct Dinic
{ edge edges[M];
int head[N], nxt[M], tot; int L, R; inline void init()
{ memset(head, -1, sizeof(head));
tot = 0;
} void add_edge(int x, int y, int z)
{ edges[tot] = edge(x, y, 0, z);
nxt[tot] = head[x];
head[x] = tot++;
edges[tot] = edge(y, x, 0, 0);
nxt[tot] = head[y];
head[y] = tot++;
} int s, t; int d[N]; bool bfs()
{ memset(d, -1, sizeof(d));
queue<int> q;
q.push(s);
d[s] = 0;
while (!q.empty())
{ int x = q.front(); q.pop();
for (int i = head[x]; ~i; i = nxt[i])
{ edge & e = edges[i];
if (vis[e.to] && e.cap > e.flow && d[e.to] == -1)
{ d[e.to] = d[x] + 1;
q.push(e.to);
}
}
}
return d[t] != -1;
} int cur[N]; int dfs(int x, int a)
{ if (x == t || a == 0) return a;
int flow = 0, f;
for (int & i = cur[x]; ~i; i = nxt[i])
{ edge & e = edges[i];
if (vis[e.to] && d[e.to] == d[x] + 1 && (f = dfs(e.to, min(a, e.cap-e.flow))) > 0)
{ e.flow += f;
edges[i^1].flow -= f;
a -= f;
flow += f;
if (!a) break;
}
}
return flow;
} int maxflow(int _s, int _t)
{ s = _s, t = _t;
int flow = 0;
while (bfs())
{ for (int i = L; i <= R; i++)
cur[i] = head[i];
flow += dfs(s, INF);
}
return flow;
}
} dinic; int S, T; int in[N]; int num[N]; inline int id(int x, int y) { return (x-1)*m + y; } void topo()
{ queue<int> q;
for (int i = 1; i <= n*m; i++)
if (!in[i]) q.push(i);
while (!q.empty())
{ int x = q.front(); q.pop();
vis[x] = 1;
for (int i = dinic.head[x]; ~i; i = dinic.nxt[i])
{ edge & e = dinic.edges[i];
if (e.to == S || e.to == T || in[e.to] == 0 || e.cap > e.flow)
continue;
if ((--in[e.to]) == 0)
q.push(e.to);
}
}
} void build()
{ S = n * m + 1, T = n * m + 2;
dinic.init();
dinic.L = 0, dinic.R = n * m + 2;
for (int i = 1; i <= n; i++)
{ for (int j = 1; j <= m; j++)
{ if (val[i][j] > 0)
dinic.add_edge(S, id(i, j), val[i][j]);
if (val[i][j] < 0)
dinic.add_edge(id(i, j), T, -val[i][j]);
for (int k = 0; k < vec[i][j].size(); k++)
{ dinic.add_edge(id(vec[i][j][k].first, vec[i][j][k].second), id(i, j), INF);
in[id(vec[i][j][k].first, vec[i][j][k].second)]++;
}
if (j > 1)
dinic.add_edge(id(i, j-1), id(i, j), INF),
in[id(i, j-1)]++;
}
}
} int main()
{ scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{ int l;
scanf("%d %d", &val[i][j], &l);
num[id(i, j)] = val[i][j];
for (int k = 1; k <= l; k++)
{ int x, y;
scanf("%d %d", &x, &y);
x++, y++;
vec[i][j].push_back(make_pair(x, y));
}
}
build();
topo();
int ans = 0;
for (int i = 1; i <= n*m; i++)
if (vis[i] && num[i] > 0)
ans += num[i];
vis[S] = vis[T] = 1;
ans -= dinic.maxflow(S, T);
printf("%d\n", ans);
return 0;
}

【BZOJ1565】【NOI2009】植物大战僵尸的更多相关文章

  1. 【最大权闭合子图 tarjan】bzoj1565: [NOI2009]植物大战僵尸

    dinic+tarjan板子练手题 Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其 中P ...

  2. BZOJ1565: [NOI2009]植物大战僵尸

    Description Input Output 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. Sample Input 3 2 10 0 20 0 ...

  3. BZOJ1565——[NOI2009]植物大战僵尸

    1.题意:有一些点,点与点之间有保护关系,每个点都有一个权值,求能获得的最大值 2.分析:裸的最大权闭合图,用网络流进行求解,然后我们发现点与点之间的保护关系可能构成环,这样网络流是无法处理的,然后我 ...

  4. 【bzoj1565】 NOI2009—植物大战僵尸

    http://www.lydsy.com/JudgeOnline/problem.php?id=1565 (题目链接) 题意 给出$n*m$的棋盘,僵尸攻击每个格子可以获得$v$的分数,每个格子又会保 ...

  5. 【bzoj1565】[NOI2009]植物大战僵尸

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

  6. 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  7. P2805 [NOI2009]植物大战僵尸

    题目地址:P2805 [NOI2009]植物大战僵尸 最大权闭合子图 若有向图 \(G\) 的子图 \(V\) 满足: \(V\) 中顶点的所有出边均指向 \(V\) 内部的顶点,则称 \(V\) 是 ...

  8. COGS410. [NOI2009] 植物大战僵尸

    410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:pvz.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] Plants vs ...

  9. BZOJ 1565: [NOI2009]植物大战僵尸

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

  10. 【刷题】BZOJ 1565 [NOI2009]植物大战僵尸

    Description Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻. ...

随机推荐

  1. 能够附加图片的标签控件iOS项目源码

    这个源码案例是能够附加图片的标签控件,源码JTImageLabel,JTImageLabel能够附加图片的标签Label控件,图片可以随意更换.位置也能够很好的控制.效果图: <ignore_j ...

  2. SAP computer之input and MAR

    Input and MAR Below the program counter is the input and MAR block. It includes the address and data ...

  3. Assembly之instruction之Register Mode

    Assembler Code Content of ROM MOV R10,R11 MOV R10,R11 Length: One or two words Operation: Move the c ...

  4. turn.js中文API 写一个翻页效果的参数详细解释

    $('.flipbook').turn({     width: 922,     height: 600,     elevation: 50,     gradients: true,     a ...

  5. .Net Core 中X509Certificate2 私钥保存为 pem 的方法

    在自己签发CA证书和颁发X509证书时,私钥通过下面的方法保存为PEM 相关代码可以已经提交在了 https://github.com/q2g/q2g-helper-pem-nuget/pull/13 ...

  6. Java---23种设计模式(九)------组合模式

    一.什么是组合模式 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象. 组合模式依据树形结构来组合对象,用来表示部分以及整体层次. 这种类型的 ...

  7. 【转载】Java IO 转换流 字节转字符流

    字节流输入字节流:---------| InputStream 所有输入字节流的基类. 抽象类.------------| FileInputStream 读取文件的输入字节流.----------- ...

  8. TestNg学习一

    简介 TestNG是Java中的一个测试框架, 类似于JUnit 和NUnit,   功能都差不多, 只是功能更加强大,使用也更方便 Java中已经有一个JUnit的测试框架了.  TestNG比JU ...

  9. PAT_A1144#The Missing Number

    Source: PAT A1144 The Missing Number (20 分) Description: Given N integers, you are supposed to find ...

  10. appium滑动

    在app应用日常使用过程中,会经常用到在屏幕滑动操作.如刷朋友圈上下滑操作.浏览图片左右滑动操作等.在自动化脚本该如何实现这些操作呢? 在Appium中模拟用户滑动操作需要使用swipe方法,该方法定 ...