zoukankan      html  css  js  c++  java
  • 士兵占领

    题目

    洛谷

    做法

    考虑最多能删的点

    (S)向每行所代表的点连(该行最多能删的点)容量的边,每列向(T)连(同理)的边

    每个存在的格子((x,y))(x)(y)(1)容量的边

    My complete code

    #include<bits/stdc++.h>
    #include<queue>
    using namespace std;
    typedef int LL;
    const LL maxn=1e5+9,inf=0x3f3f3f3f;
    struct node{
    	LL to,next,f;
    }dis[maxn];
    LL num,S,T,n,m,k;
    LL head[309],L[109],R[109],del[109][2],lev[309];
    bool visit[109][109],mark[309];
    inline void Add(LL u,LL v,LL f){
    	dis[++num]=(node){v,head[u],f}, head[u]=num;
    }
    inline LL Bfs(){
    	queue<LL> que; que.push(S);
    	memset(lev,0,sizeof(lev)),memset(mark,false,sizeof(mark));;
    	mark[S]=true;
        while(que.size()){
        	LL u(que.front()); que.pop();
        	for(LL i=head[u];~i;i=dis[i].next){
        		LL v(dis[i].to);
        		if(!mark[v] && dis[i].f){
        			lev[v]=lev[u]+1;
        			mark[v]=true;
        			que.push(v);
    			}
    		}
    	}return mark[T];
    }
    LL Dfs(LL u,LL f){
    	if(u==T) return f;
    	LL tmp(f),now;
    	for(LL i=head[u];~i;i=dis[i].next){
    		LL v(dis[i].to);
    		if(tmp && dis[i].f && lev[v]==lev[u]+1){
    			if(now=Dfs(v,min(tmp,dis[i].f))){
    				dis[i].f-=now, dis[i^1].f+=now;
    				tmp-=now;
    			}else lev[v]=-1;
    		}
    		if(!tmp) break;
    	}return f-tmp;
    }
    inline void Dinic(){
    	LL ans(0);
    	while(Bfs())
    	    ans+=Dfs(S,inf);
    	printf("%d",n*m-k-ans);
    }
    int main(){
    	cin>>n>>m>>k;
    	memset(head,-1,sizeof(head)), num=-1; 
    	for(LL i=1;i<=n;++i) cin>>L[i];
    	for(LL i=1;i<=m;++i) cin>>R[i];
    	for(LL i=1;i<=k;++i){
    		LL x,y; cin>>x>>y;
    		visit[x][y]=true;
    		++del[x][0], ++del[y][1];
    	}
    	for(LL i=1;i<=n;++i)
    	    for(LL j=1;j<=m;++j)
    	        if(!visit[i][j]){
    	        	Add(i,j+n,1), Add(j+n,i,0);
    			}
    	S=n+m+1, T=S+1;
    	for(LL i=1;i<=n;++i){
    		LL now(m-del[i][0]-L[i]);
    		if(now<0){
    			printf("JIONG!");
    			return 0;
    		}
    	    Add(S,i,now), Add(i,S,0);
    	}
    	for(LL i=1;i<=m;++i){
    		LL now(n-del[i][1]-R[i]);
    		if(now<0){
    			printf("JIONG!");
    			return 0;
    		}
    	    Add(i+n,T,now), Add(T,i+n,0);
    	}
    	Dinic();
    	return 0;
    }
    
  • 相关阅读:
    HTML编写需要注意的事项
    Java中this、super用法
    多态性的表现形式
    面向对象
    用java实现冒泡排序法
    第一堂java web课
    mysql 复制中的 paxso 的两阶段和事务两阶段的区别
    github删除仓库
    git的介绍及使用
    github的介绍
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10415850.html
Copyright © 2011-2022 走看看