zoukankan      html  css  js  c++  java
  • 【BZOJ1565】【NOI2009】植物大战僵尸 网络流 最大权闭合子图

    题目大意

    ​  给你一个(n imes m)的地图,每个格子上都有一颗植物,有的植物能保护其他植物。僵尸从右往左进攻,每吃掉一颗植物就可以得到(a_{i,j})的收益((a_{i,j})可以是负数)。求僵尸的最大收益

    ​  (1leq nleq20,1leq mleq30)

    题解

    ​  这种一个东西可以保护另一个东西而且数据范围那么小的题目显然是最大权闭合子图。

    ​  僵尸从右往左进攻,所以一棵植物可以保护它左边的植物。

    ​  如果保护关系形成一个环,就都不能选。

    ​  直接套模板即可。

    ​  可能需要一些优化

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<ctime>
    #include<utility>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    struct list
    {
    	int v[1000010];
    	int w[1000010];
    	int t[1000010];
    	int h[1010];
    	int n;
    	list()
    	{
    		memset(h,0,sizeof h);
    		n=0;
    	}
    	void add(int x,int y,int z)
    	{
    		n++;
    		v[n]=y;
    		w[n]=z;
    		t[n]=h[x];
    		h[x]=n;
    	}
    };
    list l,l2;
    void add(int x,int y,int z)
    {
    	l.add(x,y,z);
    	l.add(y,x,0);
    }
    int n,m;
    int w[110][110];
    int gx[1010];
    int gy[1010];
    int id(int x,int y)
    {
    	return (x-1)*m+y;
    }
    int vis[1010];
    int b[1010];
    void dfs(int x)
    {
    	vis[x]=1;
    	int i;
    	for(i=l2.h[x];i;i=l2.t[i])
    	{
    		if(!vis[l2.v[i]])
    			dfs(l2.v[i]);
    		if(b[l2.v[i]]||vis[l2.v[i]]==1)
    		{
    //			w[gx[x]][gy[x]]=-10000000;
    			b[x]=1;
    		}
    	}
    	vis[x]=2;
    }
    int d[1010];
    int S,T;
    int c[30][40][30][40];
    int bfs()
    {
    	memset(d,-1,sizeof d);
    	queue<int> q;
    	q.push(S);
    	d[S]=0;
    	int x,i;
    	while(!q.empty())
    	{
    		x=q.front();
    		q.pop();
    		for(i=l.h[x];i;i=l.t[i])
    			if(l.w[i]&&d[l.v[i]]==-1)
    			{
    				d[l.v[i]]=d[x]+1;
    				if(l.v[i]==T)
    					return 1;
    				q.push(l.v[i]);
    			}
    	}
    	return 0;
    }
    int op(int x)
    {
    	return ((x-1)^1)+1;
    }
    int dfs(int x,int flow)
    {
    	if(x==T)
    		return flow;
    	int c,s=0,i;
    	for(i=l.h[x];i;i=l.t[i])
    		if(l.w[i]&&d[l.v[i]]==d[x]+1)
    		{
    			c=dfs(l.v[i],min(flow,l.w[i]));
    			s+=c;
    			flow-=c;
    			l.w[i]-=c;
    			l.w[op(i)]+=c;
    			if(!flow)
    				break;
    		}
    	if(flow)
    		d[x]=-1;
    	return s;
    }
    int main()
    {
    	memset(b,0,sizeof b);
    	memset(c,0,sizeof c);
    //	freopen("bzoj1565.in","r",stdin);
    //	freopen("bzoj1565.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	S=n*m+1;
    	T=S+1;
    	int sum=0;
    	int i,j,k,o,x,y,u;
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		{
    			scanf("%d",&w[i][j]);
    			gx[id(i,j)]=i;
    			gy[id(i,j)]=j;
    			scanf("%d",&u);
    			for(k=1;k<=u;k++)
    			{
    				scanf("%d%d",&x,&y);
    				x++;
    				y++;
    				c[i][j][x][y]=1;
    			}
    			if(j>1)
    				c[i][j][i][j-1]=1;
    			for(x=1;x<=n;x++)
    				for(y=1;y<=m;y++)
    					if(c[i][j][x][y])
    						l2.add(id(x,y),id(i,j),0);
    		}
    	memset(vis,0,sizeof vis);
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    			if(!vis[id(i,j)])
    				dfs(id(i,j));
    	for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)	
    			if(!b[id(i,j)])
    			{
    				if(w[i][j]>0)
    				{
    					sum+=w[i][j];
    					add(S,id(i,j),w[i][j]);
    				}
    				else
    					add(id(i,j),T,-w[i][j]);
    				for(x=1;x<=n;x++)
    					for(y=1;y<=m;y++)
    						if(c[i][j][x][y])
    							if(!b[id(x,y)])
    								add(id(x,y),id(i,j),0x7fffffff);
    			}
    	int ans=0;
    	while(bfs())
    		ans+=dfs(S,0x7fffffff);
    	printf("%d
    ",sum-ans);
    	return 0;
    }
    
  • 相关阅读:
    Android 2.2 r1 API 中文文档系列(11) —— RadioButton
    Android API 中文 (15) —— GridView
    Android 中文 API (16) —— AnalogClock
    Android2.2 API 中文文档系列(7) —— ImageButton
    Android2.2 API 中文文档系列(6) —— ImageView
    Android 2.2 r1 API 中文文档系列(12) —— Button
    Android2.2 API 中文文档系列(8) —— QuickContactBadge
    [Android1.5]TextView跑马灯效果
    [Android1.5]ActivityManager: [1] Killed am start n
    Android API 中文(14) —— ViewStub
  • 原文地址:https://www.cnblogs.com/ywwyww/p/8510677.html
Copyright © 2011-2022 走看看