zoukankan      html  css  js  c++  java
  • 【NOI2009-DAY2-T1】【BZOJ1565】—植物大战僵尸(最大权闭合子图+拓扑排序)

    传送门

    估计是当天签到题

    考虑到如果一株植物AA被另一株植物BB给保护着,那就必须要先吃掉植物BB才可以吃掉AA,

    那考虑我们将所有被保护的植物向保护其的植物连一条边,表示要吃掉保护它的植物
    那么我们现在就相当于是在找图的一个权闭合子图了(如果不会或是不知道的权闭合子图的自行百度吧)

    从源点向所有贡献为正的点连一条边权为点权的边,所有贡献为负的点向汇点连一条边权为点权绝对值的边

    这样跑出来的最大流=最小割=最大权闭合子图

    但注意到有可能保护关系形成了一个环,这时候显然是不可能攻击环上植物的

    先拓扑排序排除一下环就是了

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=805;
    const int M=1000005;
    const int inf=19260817;
    int n,m,cnt=1,adj[N],nxt[M<<1],to[M<<1],cap[M<<1],val[N],in[N],lev[N],vis[N],tp[N],str,des,ans;
    inline int pos(int x,int y){
    	return (y-1)*m+x;
    }
    inline void addedge(int u,int v,int w){
    	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,cap[cnt]=w;
    	nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,cap[cnt]=0;
    }
    inline void topsort(){
    	queue<int> q;
    	for(int i=1;i<=n*m;i++){
    		if(!in[i])q.push(i);
    	}
    	while(!q.empty()){
    		int u=q.front();q.pop();vis[u]=1;
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			in[v]--;
    			if(!in[v])q.push(v);
    		}
    	}
    }
    inline bool bfs(){
    	memset(lev,-1,sizeof(lev));
    	queue<int> q;
    	q.push(str),lev[str]=0;
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int e=adj[u];e;e=nxt[e]){
    			int v=to[e];
    			if(cap[e]>0&&vis[v]&&lev[v]==-1){
    				lev[v]=lev[u]+1;
    				q.push(v);
    				if(v==des)return true;
    			}
    		}
    	}
    	return false;
    }
    int dinic(int u,int flow){
    	if(u==des)return flow;
    	int res=0;
    	for(int &e=tp[u];e;e=nxt[e]){
    		int v=to[e];
    		if(cap[e]>0&&vis[v]&&lev[v]==lev[u]+1){
    			int mn=dinic(v,min(flow-res,cap[e]));
    			res+=mn,cap[e]-=mn,cap[e^1]+=mn;
    		}
    	}
    	return res;
    }
    inline int solve(){
    	int res=0;
    	while(bfs()){
    		memcpy(tp,adj,sizeof(adj));
    		res+=dinic(str,inf);
    	}
    	return res;
    }
    int main(){
    	n=read(),m=read();str=n*m+1,des=str+1;
    	for(int i=1;i<=m*n;i++){
    		val[i]=read();
    		int w=read();
    		for(int j=1;j<=w;j++){
    			int y=read()+1,x=read()+1;
    			addedge(pos(x,y),i,inf);in[pos(x,y)]++;
    		}
    		if(i%m){
    			addedge(i,i+1,inf);in[i]++;
    		}
    	}
    	topsort();
    	vis[str]=vis[des]=1;
    	for(int i=1;i<=n*m;i++){
    		if(!vis[i])continue;
    		if(val[i]>0)addedge(str,i,val[i]),ans+=val[i];
    		if(val[i]<0)addedge(i,des,-val[i]);
    	}
    	cout<<(ans-solve())<<'
    ';
    }
    
  • 相关阅读:
    CSS Modules
    回调地狱
    css实现双色饼图
    vue项目中使用less
    pug(jade) 学习笔记
    React组件proptypes, ref
    react+express实现跨域
    react高阶组件
    Oracle数据库出现锁表情况分析
    JPA常用注解记录
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366326.html
Copyright © 2011-2022 走看看