Bzoj1565:[NOI2009]植物大战僵尸:拓扑排序+网络流
2016-07-17 09:37
525 查看
题目链接:1565:[NOI2009]植物大战僵尸
显然的最大权闭合图模型,但是裸上是错的
每个植物相他所攻击的位置连边,如果形成一个环那么这个换必然无解
进一步,这个环所保护的点都不能取到
所以我们拓扑排序求出可以干掉的植物集合再做网络流即可
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000010;
const int inf=0x7fffffff/3;
int n,m,tot=1,h[maxn],In[maxn],S,T;
struct edge{int to,next,w;}G[maxn];
int cur[maxn],vis[maxn],val[maxn],ans=0;
bool flag[maxn];
void add(int x,int y,int z){
In[x]++;
G[++tot].to=y;G[tot].next=h[x];h[x]=tot;G[tot].w=z;
G[++tot].to=x;G[tot].next=h[y];h[y]=tot;G[tot].w=0;
}
void toposort(){
queue<int>q;
for (int i=S;i<=T;++i) if (!In[i]) q.push(i);
while (!q.empty()){
int u=q.front(); q.pop(); flag[u]=1;
if (val[u]>0) ans+=val[u];
for (int i=h[u];i;i=G[i].next){
int v=G[i].to;
if (!G[i].w){
In[v]--;
if (!In[v]) q.push(v);
}
}
}
}
bool bfs(){
for (int i=S;i<=T;++i) vis[i]=-1;
queue<int>q; q.push(S); vis[S]=0;
while (!q.empty()){
int u=q.front(); q.pop();
for (int i=h[u];i;i=G[i].next){
int v=G[i].to;
if (vis[v]==-1&&G[i].w>0&&flag[v]){
vis[v]=vis[u]+1;
q.push(v);
}
}
}return vis[T]!=-1;
}
int dfs(int x,int f){
if (x==T||!f) return f;
int used=0,w;
for (int i=cur[x];i;i=G[i].next)
if (vis[G[i].to]==vis[x]+1){
w=f-used;
w=dfs(G[i].to,min(G[i].w,w));
G[i].w-=w; G[i^1].w+=w;
used+=w; if (G[i].w) cur[x]=i;
if (used==f) return used;
}
if (!used) vis[x]=-1;
return used;
}
int dinic(){
int ret=0;
while (bfs()){
for (int i=S;i<=T;++i) cur[i]=h[i];
ret+=dfs(S,inf);
}return ret;
}
int main(){
scanf("%d%d",&n,&m);
S=0; T=n*m+1;
for (int i=1;i<=n*m;++i){
scanf("%d",&val[i]);
if (val[i]>0) add(S,i,val[i]);
else add(i,T,-val[i]);
int a,b,c;
scanf("%d",&a);
for (int j=1;j<=a;++j){
scanf("%d%d",&b,&c);
add(b*m+c+1,i,inf);
}
if (i%m!=0) add(i,i+1,inf);//选了左侧必须先选右侧
}
toposort();
printf("%d",ans-dinic());
}
显然的最大权闭合图模型,但是裸上是错的
每个植物相他所攻击的位置连边,如果形成一个环那么这个换必然无解
进一步,这个环所保护的点都不能取到
所以我们拓扑排序求出可以干掉的植物集合再做网络流即可
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000010;
const int inf=0x7fffffff/3;
int n,m,tot=1,h[maxn],In[maxn],S,T;
struct edge{int to,next,w;}G[maxn];
int cur[maxn],vis[maxn],val[maxn],ans=0;
bool flag[maxn];
void add(int x,int y,int z){
In[x]++;
G[++tot].to=y;G[tot].next=h[x];h[x]=tot;G[tot].w=z;
G[++tot].to=x;G[tot].next=h[y];h[y]=tot;G[tot].w=0;
}
void toposort(){
queue<int>q;
for (int i=S;i<=T;++i) if (!In[i]) q.push(i);
while (!q.empty()){
int u=q.front(); q.pop(); flag[u]=1;
if (val[u]>0) ans+=val[u];
for (int i=h[u];i;i=G[i].next){
int v=G[i].to;
if (!G[i].w){
In[v]--;
if (!In[v]) q.push(v);
}
}
}
}
bool bfs(){
for (int i=S;i<=T;++i) vis[i]=-1;
queue<int>q; q.push(S); vis[S]=0;
while (!q.empty()){
int u=q.front(); q.pop();
for (int i=h[u];i;i=G[i].next){
int v=G[i].to;
if (vis[v]==-1&&G[i].w>0&&flag[v]){
vis[v]=vis[u]+1;
q.push(v);
}
}
}return vis[T]!=-1;
}
int dfs(int x,int f){
if (x==T||!f) return f;
int used=0,w;
for (int i=cur[x];i;i=G[i].next)
if (vis[G[i].to]==vis[x]+1){
w=f-used;
w=dfs(G[i].to,min(G[i].w,w));
G[i].w-=w; G[i^1].w+=w;
used+=w; if (G[i].w) cur[x]=i;
if (used==f) return used;
}
if (!used) vis[x]=-1;
return used;
}
int dinic(){
int ret=0;
while (bfs()){
for (int i=S;i<=T;++i) cur[i]=h[i];
ret+=dfs(S,inf);
}return ret;
}
int main(){
scanf("%d%d",&n,&m);
S=0; T=n*m+1;
for (int i=1;i<=n*m;++i){
scanf("%d",&val[i]);
if (val[i]>0) add(S,i,val[i]);
else add(i,T,-val[i]);
int a,b,c;
scanf("%d",&a);
for (int j=1;j<=a;++j){
scanf("%d%d",&b,&c);
add(b*m+c+1,i,inf);
}
if (i%m!=0) add(i,i+1,inf);//选了左侧必须先选右侧
}
toposort();
printf("%d",ans-dinic());
}
相关文章推荐
- 详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)
- 初学图论-Kahn拓扑排序算法(Kahn's Topological Sort Algorithm)
- HDU 3342
- Poj2638 网络流+最短路+二分答案
- BZOJ3275 Number (最小割)
- BZOJ2809——[Apio2012]dispatching
- BZOJ2809——[Apio2012]dispatching
- [笔记] 网络流-最大流 POJ-1273\HDU-4240
- 上下界网络流初探
- 2367:Genealogical tree
- Edmonds-Karp 最大流 hdu 1532 Drained Ditches
- 最长回文子串(转载自网易博客:鼻子很帅的猪)
- 信息竞赛学习笔记:POJ3579中位数(二分)
- 网络流_poj1273
- POJ 1273 Drainage Ditches 最大流 dinic
- POJ1273-Drainage Ditches
- 【网络流】复杂的大门
- ACM/ICPC World Finals 2013 C Surely You Congest
- BZOJ 1502 NOI 2005 月下柠檬树
- nike roshe női