记录编号 249086 评测结果 AAAAAAAAAA
题目名称 [NOI 2009]植物大战僵尸 最终得分 100
用户昵称 GravatarTenderRun 是否通过 通过
代码语言 C++ 运行时间 0.905 s
提交时间 2016-04-11 22:37:10 内存使用 25.90 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxr=50,maxc=50;
const int maxn=1050;
const int maxm=200010;
const int INF=23333333;
int R,C,id[maxr][maxc],def[maxr*maxc],G[maxr*maxc][maxr*maxc],sum;
int cnt=1,fir[maxn],nxt[maxm<<1],to[maxm<<1],cap[maxm<<1],v[maxr][maxc];
void addedge(int a,int b,int c){
	nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;cap[cnt]=c;
}
int dis[maxn],gap[maxn],path[maxn],fron[maxn];
queue<int>q;
void BFS(){
	memset(dis,0,sizeof(dis));
	dis[R*C+1]=1;q.push(R*C+1);
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=fir[x];i;i=nxt[i])
			if(!dis[to[i]]&&!def[to[i]])
				dis[to[i]]=dis[x]+1,
					q.push(to[i]);
	}
}
int ISAP(){
	BFS();
	for(int i=0;i<=R*C+1;i++){
		gap[dis[i]]++;
		fron[i]=fir[i];
	}
	int p=0,f,ret=0;
	while(dis[0]<=R*C+2){
		if(p==R*C+1){
			f=INF;
			while(p){
				f=min(f,cap[path[p]]);
				p=to[path[p]^1];
			}
			p=R*C+1;ret+=f;
			while(p){
				cap[path[p]]-=f;
				cap[path[p]^1]+=f;
				p=to[path[p]^1];
			}
		}
		int &ii=fron[p];
		for(;ii;ii=nxt[ii])
			if(cap[ii]&&dis[to[ii]]==dis[p]-1&&!def[to[ii]])
				break;
		if(ii)
			path[p=to[ii]]=ii;
		else{
			if(--gap[dis[p]]==0)break;
			int Min=R*C+3;
			for(int i=fir[p];i;i=nxt[i])
				if(cap[i]&&!def[to[i]])
					Min=min(Min,dis[to[i]]);
			++gap[dis[p]=Min+1];
			fron[p]=fir[p];
			if(p)p=to[path[p]^1];		
		}		
	}
	return ret;
}
void DFS(int x){
	for(int i=1;i<=R*C;i++)
		if(!def[i]&&G[x][i]){
			def[i]=true;
			DFS(i);
		}
}
int main(){
	freopen("pvz.in","r",stdin);
	freopen("pvz.out","w",stdout);
	scanf("%d%d",&R,&C);
	for(int i=1;i<=R;i++)
		for(int j=1;j<=C;j++)
			id[i][j]=(i-1)*C+j;
	for(int i=1;i<=R;i++)
		for(int j=1,x,a,b;j<=C;j++){
			scanf("%d%d",&v[i][j],&x);
			while(x--){
				scanf("%d%d",&a,&b);a++;b++;
				G[id[i][j]][id[a][b]]=true;
				addedge(id[a][b],id[i][j],INF);
				addedge(id[i][j],id[a][b],0);
			}
			if(j>1){
				G[id[i][j]][id[i][j-1]]=true;
				addedge(id[i][j-1],id[i][j],INF);
				addedge(id[i][j],id[i][j-1],0);
			}
		}
			

	for(int k=1;k<=R*C;k++)
		for(int i=1;i<=R*C;i++)
			for(int j=1;j<=R*C;j++)
				G[i][j]|=G[i][k]&&G[k][j];
	
	for(int i=1;i<=R*C;i++)
		if(G[i][i])
			def[i]=true;
	
	for(int i=1;i<=R*C;i++)
		if(def[i])
			DFS(i);		
		
	for(int i=1;i<=R;i++)
		for(int j=1;j<=C;j++)
			if(!def[id[i][j]]){
				if(v[i][j]>0){
					sum+=v[i][j];
					addedge(0,id[i][j],v[i][j]);
					addedge(id[i][j],0,0);
				}
				else
					addedge(id[i][j],R*C+1,-v[i][j]),
					addedge(R*C+1,id[i][j],0);	
			}
			
	printf("%d\n",sum-ISAP());		
	return 0;
}