• 【BZOJ3504】【CQOI2014】—危桥(最大流建模)


    传送门

    不错的一道网络流连手题

    一般第一眼都会直接想到的一种似乎正确的做法:

    对于危桥连一个流量为11的边,普通桥连一条infinf的边
    源点向al,blal,blan,bnan,bn的边,a2,b2a2,b2向汇点连一条为an,bnan,bn的边
    看是不是满流

    然而这样是错的…

    比如这样

    在这里插入图片描述

    很明显是错的

    那么怎么办?

    我们考虑交换其中一对源汇点
    然后再跑一次,看是不是仍然是最大流?

    为什么是对的呢?

    假设我们交换的是bl,b2bl,b2
    如果流满了
    考虑两种情况:


    1.alalb2b2流满的

    由于第一次的时候alalblbl可以流满
    那也就是说blblb2b2也可以流满了
    又第一次blbl,第二次b2b2都和a2a2能流满
    alal也总可以流给a2a2
    那也就说是可以的


    2.alala2a2流满的

    那不用说了,既然alal可以流满a2a2,那肯定就是可以了的


    所以如果两次都流满了,那肯定就是可以的
    反之肯定不行

    #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=71;
    const int M=5005;
    const int inf=20030224;
    int adj[N],nxt[M],to[M],cap[M],tp[N],lev[N],n,cnt,str,des,as,at,an,bs,bt,bn;
    char edg[N][N];
    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 bool bfs(){
    	queue<int> q;
    	memset(lev,-1,sizeof(lev));
    	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&&lev[v]==-1){
    				lev[v]=lev[u]+1,q.push(v);
    				if(v==des)return true;
    			}
    		}
    	}
    	return false;
    }
    inline 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(lev[v]==lev[u]+1&&cap[e]>0){
    			int mn=dinic(v,min(flow-res,cap[e]));
    			cap[e]-=mn,cap[e^1]+=mn,res+=mn;
    			if(flow==res)return res;
    		}
    	}
    	return res;
    }
    inline int solve(){
    	int res=0;
    	while(bfs()){
    		memcpy(tp,adj,sizeof(adj));
    		res+=dinic(str,inf);
    	}
    	return res;
    }
    inline void buildedge(){
    	memset(adj,0,sizeof(adj)),memset(cap,0,sizeof(cap)),cnt=1;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			switch(edg[i][j]){
    				case 'O':{
    					addedge(i,j,1);
    					break;
    				}
    				case 'N':{
    					addedge(i,j,inf);
    					break;
    				}
    				case 'X':{
    					break;
    				}
    			}
    		}
    	}
    }
    int main(){
    	while(scanf("%d",&n)!=EOF){
    		as=read()+1,at=read()+1,an=read(),bs=read()+1,bt=read()+1,bn=read();
    		str=n+1,des=n+2;
    		for(int i=1;i<=n;i++)scanf("%s",edg[i]+1);
    		buildedge();
    		addedge(str,as,an),addedge(str,bs,bn),addedge(at,des,an),addedge(bt,des,bn);
    		int fres=solve();
    		buildedge();
    		addedge(str,as,an),addedge(str,bt,bn),addedge(at,des,an),addedge(bs,des,bn);
    		int res=solve();
    		if(res==an+bn&&fres==an+bn)cout<<"Yes"<<'
    ';
    		else cout<<"No"<<'
    ';
    	}
    }
    
  • 相关阅读:
    局域网主机A向主机B发送ip数据报的过程
    用户使用浏览器访问万维网经历的步骤
    sql
    PMP:总概
    LINQ
    下拉框
    PMP:项目采购管理
    PMP:项目风险管理
    PMP:沟通管理。相关方管理
    PMP:项目资源管理
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366330.html
Copyright © 2020-2023  润新知