kuangbin专题十一 网络流专题(2020/12/08-2020/12/16) 15道

专题链接kuangbin专题十一 网络流

题目

POJ 3436 ACM Computer Factory
POJ 3281 Dining
POJ 1087 A Plug for UNIX
POJ 2195 Going Home
POJ 2516 Minimum Cost
POJ 1459 Power Network
HDU 4280 Island Transport
HDU 4292 Food
HDU 4289 Control
UVA 10480 Sabotage
HDU 2732 Leapin’ Lizards
HDU 3338 Kakuro Extension
HDU 3605 Escape
HDU 3081 Marriage Match II
HDU 3416 Marriage Match IV

个人模板

dinic模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
#define Ri(x) scanf("%d",&(x))
#define Rii(x,y) scanf("%d%d",&x,&y)
#define Riii(x,y,z) scanf("%d%d%d",&x,&y,&z)
const int N=300,M=1e5,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flw,nxt;
}e[M];
int fst[N],h[N];
int n,m,cnt;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
bool bfs(int s,int t){
    
    
	ms1(h);
	h[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(e[i].flw&&h[v]==-1){
    
    
				h[v]=h[u]+1;
				q.push(v);
				if(v==t) return 1;
			}
		} 
	}
	return 0;
}
int dfs(int u,int t,int flow){
    
    
	if(u==t) return flow;
	int rst=flow;
	for(int i=fst[u];~i&&rst;i=e[i].nxt){
    
    
		int v=e[i].v;
		if(h[v]==h[u]+1&&e[i].flw){
    
    
			int f=dfs(v,t,min(e[i].flw,rst));
			if(f){
    
    
				e[i].flw-=f;
				e[i^1].flw+=f;
				rst-=f;
			}
			else h[v]=-1;
		}
	}
	return flow-rst;
}
int mflw(int s,int t){
    
    
	int f=0,mxf=0;
	while(bfs(s,t))
		while(f=dfs(s,t,INF))
			mxf+=f;
	return mxf;
}
int main(){
    
    
	int T,s,t,u,v,w;
	Ri(T);
	while(T--){
    
    
		Rii(n,m);
		cnt=0;
		Rii(s,t);
		ms1(fst);
		rep(i,1,m){
    
    
			Riii(u,v,w);
			add(u,v,w);
		}
		printf("%d\n",mflw(s,t));
	}
	return 0;
}

ISAP模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=1e3+5,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flow,nxt;
}e[(N*N)>>1];
int pre[N],gap[N],h[N],fst[N];
int cnt,n,m;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0;
	gap[0]=1;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		} 
	}
}
int isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flow=e[i].flow;
			if(h[v]+1==h[u]&&flow){
    
    
				pre[v]=i;
				u=v;
				d=min(flow,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flow-=d;
						e[tmp^1].flow+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flow=e[i].flow;
				if(flow) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans;
} 
int main(){
    
    
	while(~scanf("%d%d",&n,&m)){
    
    
        ms1(fst);cnt=0;
        int u,v,w;
        rep(i,1,m){
    
    
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        printf("%d\n",isap(1,n,n));
    }
    return 0;
}
 

AC代码

ACM Computer Factory

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar);
const int INF=0x3f3f3f3f;
int p,n,q,ans=0;
int s[60][20],d[60][20],g[60][60],u[60],v[60],w[60];
bool vis[60],gg[60][60];
bool lin(int x,int y){
    
    
	rep(i,1,p)
		if((d[x][i]==1&&!s[y][i])||(!d[x][i]&&s[y][i]==1)) return 0;
	return 1;
}
int dfs(int S,int t,int f){
    
    
	if(S==t) return f;
	vis[S]=1;
	rep(i,1,(n+1)<<1)
		if(g[S][i]&&!vis[i]){
    
    
			int d=dfs(i,t,min(f,g[S][i]));
			if(d>0){
    
    
				g[S][i]-=d;
				g[i][S]+=d;
				return d;
			}
		}
	return 0;
}
int mflow(){
    
    
	int flow=0;
	while(1){
    
    
		ms0(vis);
		int f=dfs(1,(n+1)<<1,INF);
		if(!f) return flow;
		flow+=f;
	}
}
int main(){
    
    
	cin>>p>>n;
	rep(i,1,n){
    
    
		cin>>q;
		bool fs=1,ft=1; 
		rep(j,1,p){
    
    
			cin>>s[i][j];
			if(s[i][j]==1&&j>0) fs=0;
		}
		rep(j,1,p){
    
    
			cin>>d[i][j];
			if(!d[i][j]&&j>0) ft=0;
		}
		g[i<<1][i<<1|1]=q;
		if(fs) g[1][i<<1]=INF;
		if(ft) g[i<<1|1][(n+1)<<1]=INF;
		rep(j,1,i-1){
    
    
			if(lin(i,j)) g[i<<1|1][j<<1]=INF,gg[i][j]=1;
			if(lin(j,i)) g[j<<1|1][i<<1]=INF,gg[j][i]=1;
		}
	}
	printf("%d ",mflow());
	rep(i,1,n)
		rep(j,1,n)
			if(i!=j&&gg[i][j]&&g[i<<1|1][j<<1]!=INF){
    
    
				w[++ans]=INF-g[i<<1|1][j<<1],u[ans]=i,v[ans]=j;
			}
	printf("%d\n",ans);
	rep(i,1,ans) printf("%d %d %d\n",u[i],v[i],w[i]);
	return 0; 
} 

Dining

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;
struct edge{
    
    
	int fr,to,ca,fl;
};
vector<edge>e;
vector<int>g[405];
int a[405],p[405],n,f,d;
void add(int from,int to){
    
    
	int l;
	e.push_back((edge){
    
    from,to,1,0});
	e.push_back((edge){
    
    to,from,0,0});
//	cout<<from<<" "<<to<<endl;
	l=e.size();
	g[from].push_back(l-2);
	g[to].push_back(l-1);
}
int main(){
    
    
	cin>>n>>f>>d;
	int fi,di,t;
	for(int i=1;i<=f;i++) add(0,i);
	for(int i=1;i<=d;i++) add(f+2*n+i,f+2*n+d+1);
	for(int i=1;i<=n;i++) add(f+i*2-1,f+i*2);
	for(int i=1;i<=n;i++){
    
    
		cin>>fi>>di;
		for(int j=1;j<=fi;j++){
    
    
			cin>>t;
			add(t,f+i*2-1);
		}
		for(int j=1;j<=di;j++){
    
    
			cin>>t;
			add(f+i*2,f+n*2+t);
		}	
	}
	int flow=0;
	while(true){
    
    
		memset(a,0,sizeof(a));
		queue<int>q;
		q.push(0);
		a[0]=1<<30;
		while(!q.empty()){
    
    
			int x=q.front();
			q.pop();
			for(int i=0;i<g[x].size();i++){
    
    
				edge k=e[g[x][i]];
				if(!a[k.to]&&k.ca>k.fl){
    
    
					p[k.to]=g[x][i];
					a[k.to]=min(a[x],k.ca-k.fl);
					q.push(k.to);
				}
			}
			if(a[f+2*n+d+1]) break;
		}
		if(!a[f+2*n+d+1]) break;
		for(int u=f+2*n+d+1;u!=0;u=e[p[u]].fr){
    
    
			e[p[u]].fl+=a[f+2*n+d+1];
			e[p[u]^1].fl-=a[f+2*n+d+1];
		}
//		for(int i=0;i<e.size();i++)
//			if(e[i].fl) cout<<e[i].fr<<" "<<e[i].to<<" "<<e[i].fl<<endl;
		flow+=a[f+2*n+d+1];
//		cout<<"@"<<flow<<endl;
	}
	cout<<flow;
	return 0;	
}

A Plug for UNIX

#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=105,INF=0x3f3f3f3f;
int n,m,k,cnt=1;
int g[2000][2000];
bool vis[2000];
map<string,int>mps;
int dfs(int s,int t,int f){
    
    
	if(s==t) return f;
	vis[s]=1;
	rep(i,0,cnt)
		if(!vis[i]&&g[s][i]){
    
    
			int d=dfs(i,t,min(f,g[s][i]));
			if(d>0){
    
    
				g[s][i]-=d;
				g[i][s]+=d;
				return d;
			}
		} 
	return 0;
}
int mflow(){
    
    
	int flow=0;
	while(1){
    
    
		ms0(vis);
		int f=dfs(1,0,INF);
		if(!f) return flow;
		flow+=f;
	}
}
int main(){
    
    
	string pl,ql;
	cin>>n;
	rep(i,1,n){
    
    
		cin>>pl;
		if(mps.find(pl)==mps.end()) mps[pl]=++cnt;
		g[mps[pl]][0]=1;
	}
	cin>>m;
	rep(i,1,m){
    
    
		cin>>pl>>ql;
		if(mps.find(pl)==mps.end()) mps[pl]=++cnt;
		if(mps.find(ql)==mps.end()) mps[ql]=++cnt;
		g[1][mps[pl]]=1;
		g[mps[pl]][mps[ql]]=1;
	}
	cin>>k;
	rep(i,1,k){
    
    
		cin>>pl>>ql;
		if(mps.find(pl)==mps.end()) mps[pl]=++cnt;
		if(mps.find(ql)==mps.end()) mps[ql]=++cnt;
		g[mps[pl]][mps[ql]]=INF;
	}
	cout<<m-mflow(); 
	return 0;
}

Going Home

#include<iostream>
#include<cstring>
#include<algorithm> 
#include<cmath>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=105,INF=0x3f3f3f3f;
int g[N][N],gap[N],exl[N],exr[N],lin[N],mx[N],my[N],hx[N],hy[N];
int n,m,cntm,cnth;
bool visl[N],visr[N];
bool dfs(int x){
    
    
	visl[x]=1;
	rep(i,1,cnth){
    
    
		if(visr[i]) continue;
		int d=exl[x]+exr[i]-g[x][i];
		if(!d){
    
    
			visr[i]=1;
			if(!lin[i]||dfs(lin[i])){
    
    
				lin[i]=x;
				return 1;
			}
		}
		else if(gap[i]>d) gap[i]=d;
	}
	return 0;
}
int main(){
    
    
	char tmp;
	while(scanf("%d%d",&n,&m)){
    
    
		if(!n) break;
		ms0(lin),ms0(exr);
		fill(exl+1,exl+n+1,-INF);
		cntm=cnth=0;
		rep(i,1,n)
			rep(j,1,m){
    
    
				scanf(" %c",&tmp);
				if(tmp=='m') mx[++cntm]=i,my[cntm]=j;
				if(tmp=='H') hx[++cnth]=i,hy[cnth]=j;
			}
		rep(i,1,cntm)
			rep(j,1,cnth)
				g[i][j]=-abs(mx[i]-hx[j])-abs(my[i]-hy[j]),exl[i]=max(g[i][j],exl[i]);
		rep(i,1,cnth){
    
    
			rep(j,1,cnth) gap[j]=INF;
			while(1){
    
    
				ms0(visl),ms0(visr);
				if(dfs(i)) break;
				int d=INF;
				rep(j,1,cnth)
					if(!visr[j]) d=min(gap[j],d);
				rep(j,1,cnth){
    
    
					if(visl[j]) exl[j]-=d;
					if(visr[j]) exr[j]+=d;
				}
			}
		}
		int ans=0;
		rep(i,1,cnth) ans+=g[lin[i]][i];
		printf("%d\n",-ans);
	}
	return 0;
}

Minimum Cost

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=60,M=N<<1,INF=0x3f3f3f3f;
int n,m,k,cnt,s,t,ans;
struct edge{
    
    
	int flw,cap,w;
}g[M][M];
int d[M],pre[M],a[M],b[N][N],c[N][N],sum[N];
bool inq[M];
bool bf(int &flow,int &cost){
    
    
	rep(i,0,t) d[i]=INF;
	ms0(inq);
	d[s]=0,inq[s]=1,pre[s]=0,a[s]=INF;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		inq[u]=0;
		rep(i,1,t){
    
    
			if(g[u][i].cap>g[u][i].flw&&d[i]>d[u]+g[u][i].w){
    
    
				pre[i]=u;
				d[i]=d[u]+g[u][i].w;
				a[i]=min(a[u],g[u][i].cap-g[u][i].flw);
				if(!inq[i]){
    
    
					q.push(i);
					inq[i]=1;
				}
			}
		}	
	}
	if(d[t]==INF) return 0;
	flow+=a[t];
	cost+=d[t]*a[t];
	for(int u=t;u!=s;u=pre[u]){
    
    
		g[pre[u]][u].flw+=a[t];
		g[u][pre[u]].flw-=a[t];
	}
	return 1;
}
int mflow(int p){
    
    
	int flow=0,cost=0;
	while(bf(flow,cost));
	if(flow==sum[p]) return cost;
	return -1; 
}
int main(){
    
    
	int tmp;
	while(1){
    
    
		scanf("%d%d%d",&n,&m,&k);
		ms0(g);
		ms0(sum);
		if(!n) break;
		s=ans=0,t=n+m+1;
		bool flag=1;
		rep(i,1,n)
			rep(j,1,k){
    
    
				scanf("%d",&b[i][j]);
				sum[j]+=b[i][j];
			}
		rep(i,1,m)
			rep(j,1,k)
				scanf("%d",&c[i][j]);
		rep(i,1,k){
    
    
			rep(j,1,n)
				rep(l,1,m){
    
    
					scanf("%d",&tmp);
					g[l+n][j]=(edge){
    
    0,INF,tmp};
					g[j][l+n]=(edge){
    
    0,0,-tmp};
				}
			if(flag){
    
    
				rep(j,1,m)
					g[0][n+j]=(edge){
    
    0,c[j][i],0};
				rep(j,1,n)
					g[j][t]=(edge){
    
    0,b[j][i],0};
				tmp=mflow(i);
				if(tmp==-1) flag=0;
				else ans+=tmp;
			}
		}
		if(!flag) ans=-1;
		printf("%d\n",ans);
	}
	return 0;
}

Power Network

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=1005,M=N*N,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flow,nxt;
}e[M];
int n,np,nc,m,cnt,s,t;
int pre[N],gap[N],h[N],fst[N];
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0;
	gap[0]=1;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		}
	}
}
int isap(){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<n+2){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flow=e[i].flow;
			if(h[v]+1==h[u]&&flow){
    
    
				pre[v]=i;
				u=v;
				d=min(flow,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flow-=d;
						e[tmp^1].flow+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=n+1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flow=e[i].flow;
				if(flow) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans;
}
int main(){
    
    
	char tmp1,tmp2,tmp3;
	int u,v,z;
	while(~scanf("%d%d%d%d",&n,&np,&nc,&m)){
    
    
		cnt=0,ms1(fst),s=n,t=n+1;
		rep(i,1,m){
    
    
			scanf(" %c%d %c%d %c%d",&tmp1,&u,&tmp2,&v,&tmp3,&z);
			add(u,v,z);
		}
		rep(i,1,np){
    
    
			scanf(" %c%d %c%d",&tmp1,&u,&tmp2,&z);
			add(n,u,z);
		}
		rep(i,1,nc){
    
    
			scanf(" %c%d %c%d",&tmp1,&u,&tmp2,&z);
			add(u,n+1,z);
		}
		printf("%d\n",isap());
	}
	return 0;
}

Island Transport

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm> 
#include<queue>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=1e5+5,M=2e5+5,INF=0x3f3f3f3f;
int n,m,cnt;
int pre[N],gap[N],h[N],fst[N];
struct edge{
    
    
	int v,flow,nxt;
}e[M];
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,flow,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0,gap[0]++;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		}
	}
}
int isap(int s,int t){
    
    
	bfs(s,t);
	int ans=0,d,u=s;
	while(h[s]<n){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flow=e[i].flow;
			if(h[u]==h[v]+1&&flow){
    
    
				pre[v]=i;
				u=v;
				d=min(flow,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flow-=d;
						e[tmp^1].flow+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=n-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flow=e[i].flow;
				if(flow) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans;
}
int main(){
    
    
	int T,s,t,xmin,xmax,x,y,z;
	scanf("%d",&T);
	while(T--){
    
    
		scanf("%d%d",&n,&m);
		ms1(fst); 
		cnt=0;
		xmin=1e5+1,xmax=-1e5-1;
		rep(i,1,n){
    
    
			scanf("%d%d",&x,&y);
			if(x<xmin) xmin=x,s=i;
			if(x>xmax) xmax=x,t=i;
		}
		rep(i,1,m){
    
    
			scanf("%d%d%d",&x,&y,&z);
			add(x,y,z);
		}
		printf("%d\n",isap(s,t));
	}
	return 0;
}

Food

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring> 
#include<queue>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=205,M=N*N*6,P=N<<2,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flow,nxt;
}e[M];
int pre[P],h[P],gap[P],fst[P];
int n,f,d,cnt;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);ms0(gap);
	h[t]=0,gap[0]=1;
	queue<int>q;
	q.push(t);
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		}
	}
}
int isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flow=e[i].flow;
			if(h[v]+1==h[u]&&flow){
    
    
				u=v;
				flag=1;
				pre[v]=i;
				d=min(flow,d);
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flow-=d;
						e[tmp^1].flow+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flow=e[i].flow;
				if(flow) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans; 	
}
int main(){
    
    
	int tmp,s,t;
	char pmt;
	while(~scanf("%d%d%d",&n,&f,&d)){
    
    
		cnt=s=0,t=f+d+n*2+1;
		ms1(fst);
		rep(i,1,n)
			add(f+d+i,f+d+n+i,1);
		rep(i,1,f){
    
    
			scanf("%d",&tmp);
			add(0,i,tmp);
		}
		rep(i,1,d){
    
    
			scanf("%d",&tmp);
			add(i+f,t,tmp);
		}
		rep(i,1,n)
			rep(j,1,f){
    
    
				scanf(" %c",&pmt);
				if(pmt=='Y') add(j,f+d+i,1);
			}
		rep(i,1,n)
			rep(j,1,d){
    
    
				scanf(" %c",&pmt);
				if(pmt=='Y') add(f+d+n+i,j+f,1);
			}
		printf("%d\n",isap(s,t,t+1));	
	}
	return 0;
} 

Control

#include<stdio.h>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=1005,M=1e6+5,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flw,nxt;
}e[M];
int pre[N],fst[N],h[N],gap[N];
int cnt=0,n,m;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0,gap[0]++;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		}
	}
}
int isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flw=e[i].flw;
			if(h[v]+1==h[u]&&flw){
    
    
				pre[v]=i;
				u=v;
				d=min(flw,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flw-=d;
						e[tmp^1].flw+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flw=e[i].flw;
				if(flw) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans;
}
int main(){
    
    
	int s,t;
	while(~scanf("%d%d%d%d",&n,&m,&s,&t)){
    
    
		int tmp,u,v;
		cnt=0;
		ms1(fst);
		rep(i,1,n){
    
    
			scanf("%d",&tmp);
			add(i,i+n,tmp);
		}
		rep(i,1,m){
    
    
			scanf("%d%d",&u,&v);
			add(u+n,v,INF);
			add(v+n,u,INF);
		}
		printf("%d\n",isap(s,t+n,n<<1));
	}
	return 0;
} 

Sabotage

#include<stdio.h>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=55,M=1e4+5,INF=0x3f3f3f3f;
struct edge{
    
    
	int u,v,flw,nxt;
}e[M];
int pre[N],fst[N],h[N],gap[N];
bool fa[N],vis[N];
int cnt=0,n,m;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    u,v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    v,u,flow,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0,gap[0]++;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		}
	}
}
void isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flw=e[i].flw;
			if(h[v]+1==h[u]&&flw){
    
    
				pre[v]=i;
				u=v;
				d=min(flw,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flw-=d;
						e[tmp^1].flw+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flw=e[i].flw;
				if(flw) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	queue<int>q;
	q.push(s);
	ms0(fa),ms0(vis);
	fa[s]=vis[s]=1;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flw=e[i].flw;
				if(flw&&!vis[v]){
    
    
					fa[v]=vis[v]=1;
					q.push(v);
				}
			}
	}
	for(int i=0;i<cnt;i+=2)
		if(fa[e[i].v]!=fa[e[i+1].v]) printf("%d %d\n",e[i].v,e[i+1].v); 
	printf("\n");
}
int main(){
    
    
	int s,t;
	while(1){
    
    
		scanf("%d%d",&n,&m);
		if(!n) break;
		int tmp,u,v;
		cnt=0,s=1,t=2;
		ms1(fst);
		rep(i,1,m){
    
    
			scanf("%d%d%d",&u,&v,&tmp);
			add(u,v,tmp);
		}
		isap(s,t,n);
	}
	return 0;
} 

Leapin’ Lizards

#include<stdio.h>
#include<cstring>
#include<iostream>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int N=2e3,M=2e6,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flw,nxt;
}e[M];
int pre[N],fst[N],h[N],gap[N],mp[N][N],sx[4]={
    
    1,1,-1,-1},sy[4]={
    
    1,-1,1,-1};
int cnt,n,len,ss,d;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
bool inm(int x,int y){
    
    
	if(x<1||x>n||y<1||y>len) return 0;
	return 1;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0,gap[0]++;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		}
	}
}
void op(int i,int j){
    
    
	int dx,dy;
	rep(dd,1,d)
		rep(p,1,dd-1)
				rep(q,0,3){
    
    
					dx=sx[q]*p,dy=sy[q]*(dd-p);
						if(!inm(i+dx,j+dy)){
    
    
							add(((i-1)*len+j)*2+1,1,5);
							return;
						}
				}	
	rep(dd,1,d)
		rep(q,0,3){
    
    
			dx=((sx[q]+sy[q])*dd)>>1,dy=((sx[q]-sy[q])*dd)>>1;
			if(!inm(i+dx,j+dy)){
    
    
				add(((i-1)*len+j)*2+1,1,5);
				return;
			}
		}
}
void opt(int i,int j){
    
    
	int dx,dy;
	rep(dd,1,d)
		rep(p,1,dd-1)
			rep(q,0,3){
    
    
				dx=sx[q]*p,dy=sy[q]*(dd-p);
				if(mp[i,j]&&inm(i+dx,j+dy)&&mp[i+dx][j+dy]) add(((i-1)*len+j)*2+1,((i+dx-1)*len+j+dy)*2,INF);
			}
	rep(dd,1,d)
		rep(q,0,3){
    
    
			dx=((sx[q]+sy[q])*dd)>>1,dy=((sx[q]-sy[q])*dd)>>1;
			if(mp[i,j]&&inm(i+dx,j+dy)&&mp[i+dx][j+dy]) add(((i-1)*len+j)*2+1,((i+dx-1)*len+j+dy)*2,INF);
		}
}
int isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,D,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) D=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flw=e[i].flw;
			if(h[v]+1==h[u]&&flw){
    
    
				pre[v]=i;
				u=v;
				D=min(flw,D);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flw-=D;
						e[tmp^1].flw+=D;
						u=e[tmp^1].v;
					}
					ans+=D;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flw=e[i].flw;
				if(flw) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans;
}
int main(){
    
    
	int T;
	string k;
	scanf("%d",&T);
	rep(o,1,T){
    
    
		cnt=ss=0;
		ms1(fst); 
		ms0(mp);
		int w,dx,dy;
		scanf("%d%d",&n,&d);
		rep(i,1,n){
    
    
			cin>>k;
			len=k.size();
			rep(j,1,len){
    
    
				w=k[j-1]-'0';
				if(w){
    
    
					add(((i-1)*len+j)*2,((i-1)*len+j)*2+1,w);
					op(i,j);
					mp[i][j]=w;
				}	
			}
		}
		rep(i,1,n){
    
    
			cin>>k;
			rep(j,1,len){
    
    
				if(k[j-1]=='L'){
    
    
					ss++;
					add(0,((i-1)*len+j)<<1,1);
				}
				opt(i,j);
			}
		}
		printf("Case #%d: ",o);
		int ans=isap(0,1,n*len*2+2);
		if(ans==ss) printf("no lizard was left behind.\n");
		else if(ans==ss-1) printf("%d lizard was left behind.\n",ss-ans);
		else printf("%d lizards were left behind.\n",ss-ans);
	}
	return 0; 
}

Kakuro Extension

#include<stdio.h>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar) 
#define wz (i-1)*m+j
const int N=3e4+5,M=6e6,INF=0x3f3f3f3f;
struct edge{
    
    
	int u,v,flw,nxt;
}e[M];
struct ceil{
    
    
	int h,s;
}c[105][105];
int pre[N],gap[N],h[N],fst[N],a[105][105];
int cnt,n,m,sum;
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    u,v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    v,u,0,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0;
	gap[0]=1;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		} 
	}
}
void isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms1(a);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flow=e[i].flw;
			if(h[v]+1==h[u]&&flow){
    
    
				pre[v]=i;
				u=v;
				d=min(flow,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flw-=d;
						e[tmp^1].flw+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flow=e[i].flw;
				if(flow) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	rep(i,0,cnt-1){
    
    
		int x,y;
		if(e[i].u<=n*m){
    
    
			y=(e[i].u-1)%m+1,x=(e[i].u-y)/m+1;
			if(!(~c[x][y].s)) a[x][y]=8-e[i].flw;
		}
		if(e[i].v<=n*m){
    
    
			y=(e[i].v-1)%m+1,x=(e[i].v-y)/m+1;
			if(!(~c[x][y].s)) a[x][y]=e[i].flw;
		}
//		printf("%d %d %d %d\n",i,e[i].u,e[i].v,e[i].flw);
	}
	rep(i,1,n)
		rep(j,1,m){
    
    
			if(a[i][j]==-1) printf("_");
			else printf("%d",a[i][j]+1);
			if(j!=m) printf(" ");
			else printf("\n");
		}
} 
int main(){
    
    
	int s,t;
	string ss;
	while(~scanf("%d%d",&n,&m)){
    
    
		int nm=n*m;
		s=cnt=sum=0,t=nm*2+1;
		ms1(fst); 
		rep(i,1,n)
			rep(j,1,m){
    
    
				cin>>ss;
				if(ss[0]=='.')
					c[i][j].s=c[i][j].h=-1,sum++;
				else{
    
    
					if(ss[0]>='0'&&ss[0]<='9'){
    
    
						c[i][j].s=(ss[0]-'0')*100+(ss[1]-'0')*10+ss[2]-'0'; 
						sum++;
					}
					else c[i][j].s=0;
					if(ss[4]>='0'&&ss[4]<='9'){
    
    
						c[i][j].h=(ss[4]-'0')*100+(ss[5]-'0')*10+ss[6]-'0';
						sum++;
					}
					else c[i][j].h=0;
				}
			}
		rep(i,1,n)
			rep(j,1,m)
				if(~c[i][j].s){
    
    
					if(c[i][j].s){
    
    
						int k;
						for(k=i+1;k<=n;k++)
							if(!(~c[k][j].s)) add(wz,(k-1)*m+j,8);
							else break;
						add(0,wz,c[i][j].s-(k-i-1));
					}
					if(c[i][j].h){
    
    
						int k;
						for(k=j+1;k<=m;k++)
							if(!(~c[i][k].s)) add((i-1)*m+k,wz+nm,8);
							else break;
						add(wz+nm,t,c[i][j].h-(k-j-1));
					}
				}
		isap(s,t,sum);
	}
	return 0;
}

Escape

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
const int INF=0x3f3f3f3f,N=1050,M=3e4;
struct edge{
    
    
	int v,flow,nxt;
}e[M];
int n,m,cnt;
int pre[N],gap[N],h[N],fst[N],a[N];
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
void bfs(int s,int t){
    
    
	ms1(h);
	ms0(gap);
	queue<int>q;
	q.push(t);
	h[t]=0;
	gap[0]=1;
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(h[v]==-1){
    
    
				h[v]=h[u]+1;
				gap[h[v]]++;
				q.push(v);
			}
		} 
	}
}
int isap(int s,int t,int maxn){
    
    
	bfs(s,t);
	ms0(pre);
	int ans=0,d,u=s;
	while(h[s]<maxn){
    
    
		bool flag=0;
		if(u==s) d=INF;
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v,flow=e[i].flow;
			if(h[v]+1==h[u]&&flow){
    
    
				pre[v]=i;
				u=v;
				d=min(flow,d);
				flag=1;
				if(v==t){
    
    
					while(u!=s){
    
    
						int tmp=pre[u];
						e[tmp].flow-=d;
						e[tmp^1].flow+=d;
						u=e[tmp^1].v;
					}
					ans+=d;
				}
				break;
			}
		}
		if(!flag){
    
    
			if(!(--gap[h[u]])) break;
			int qmin=maxn-1;
			for(int i=fst[u];~i;i=e[i].nxt){
    
    
				int v=e[i].v,flow=e[i].flow;
				if(flow) qmin=min(h[v],qmin);
			}
			h[u]=qmin+1;
			gap[h[u]]++;
			if(u!=s) u=e[pre[u]^1].v;
		}
	}
	return ans;
} 
int main(){
    
    
	while(~scanf("%d%d",&n,&m)){
    
    
		int k=1<<m,tmp,s=0,t=k,sum=0;
		ms0(a);
		ms1(fst);
		rep(i,1,n){
    
    
			int num=0;
			rep(j,1,m){
    
    
				scanf("%d",&tmp);
				if(tmp) num+=(1<<(j-1)); 
			}
			a[num]++;
		}
		rep(i,1,k-1){
    
    
			if(a[i]){
    
    
				add(0,++sum,a[i]);
				int num=i,w=0;
				while(num){
    
    
					w++;
					if(num&1) add(sum,k+w,INF);
					num>>=1;
				}
			}
		}
		rep(i,1,m){
    
    
			scanf("%d",&tmp);
			add(k+i,t,tmp);
		}
		if(isap(s,t,sum+m+2)==n) printf("YES\n");
		else printf("NO\n"); 
	}
	return 0;
}

Marriage Match II

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
#define Ri(x) scanf("%d",&(x))
#define Rii(x,y) scanf("%d%d",&x,&y)
const int N=300,M=1e5,INF=0x3f3f3f3f;
struct edge{
    
    
	int u,v,flw,nxt;
}e[M];
int fst[N],h[N],g[105][105],fa[105];
int n,cnt;
int find(int x){
    
    
	return x==fa[x]?x:fa[x]=find(fa[x]);
}
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    u,v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    v,u,0,fst[v]};
	fst[v]=cnt++;
//	cout<<u<<" "<<v<<" "<<flow<<endl;
}
bool bfs(int s,int t){
    
    
	ms1(h);
	h[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(e[i].flw&&h[v]==-1){
    
    
				h[v]=h[u]+1;
				q.push(v);
				if(v==t) return 1;
			}
		} 
	}
	return 0;
}
int dfs(int u,int t,int flow){
    
    
	if(u==t) return flow;
	int rst=flow;
	for(int i=fst[u];~i&&rst;i=e[i].nxt){
    
    
		int v=e[i].v;
		if(h[v]==h[u]+1&&e[i].flw){
    
    
			int f=dfs(v,t,min(e[i].flw,rst));
			e[i].flw-=f;
			e[i^1].flw+=f;
			rst-=f;
			if(!f) h[v]=-1;
		}
	}
	return flow-rst;
}
int mflw(int s,int t){
    
    
	int flow=0,mf=0;
	while(bfs(s,t)){
    
    
		while(flow=dfs(s,t,INF))
			mf+=flow;
	}
//	rep(i,0,cnt-1) cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].flw<<endl;
	return mf;
}
bool pd(int mf,int s,int t){
    
    
	ms1(fst);
	cnt=0;
	rep(i,1,n){
    
    
		add(s,i,mf);
		add(i+n,t,mf);
	}
	rep(i,1,n)
		rep(j,1,n)
			if(g[i][j]) add(i,j+n,1);
	if(mflw(s,t)==n*mf) return 1;
	return 0;
}
int main(){
    
    
	int T,m,f,s,t,a,b;
	Ri(T);
	while(T--){
    
    
		scanf("%d%d%d",&n,&m,&f);
		s=cnt=0,t=n*2+1;
		ms0(g);
		rep(i,1,n) fa[i]=i;
		rep(i,1,m){
    
    
			Rii(a,b);
			g[a][b]=1;
		}
		rep(i,1,f){
    
    
			Rii(a,b);
			fa[find(a)]=find(b);
		}
		rep(i,1,n)
			rep(j,1,n)
				if(find(i)==find(j))
					rep(k,1,n)
						g[i][k]=g[j][k]=(g[i][k]||g[j][k]); 
		int L=0,R=100;
        while(L<R)
        {
    
    
            int mid=(L+R)>>1;
            if(pd(mid,s,t)) L=mid+1;
            else R=mid;
//            printf("\n");
        }
        printf("%d\n",L-1);
	}
	return 0;
}

Marriage Match IV

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define ms0(ar) memset(ar,0,sizeof ar)
#define ms1(ar) memset(ar,-1,sizeof ar)
#define Ri(x) scanf("%d",&(x))
#define Rii(x,y) scanf("%d%d",&x,&y)
const int N=1e3+5,M=1e5+5,INF=0x3f3f3f3f;
struct edge{
    
    
	int v,flw,nxt;
}e[M<<1];
struct Edge{
    
    
	int u,v,w,nxt;
}E[M];
struct node{
    
    
	int d,p;
	bool operator<(const node&tmp) const{
    
    
		return d>tmp.d;
	} 
}c[N]; 
int n,m,cnt,dnt;
int d[N],fst[N],Fst[N],h[N];
bool vis[N];
void dij(int s,int t){
    
    
	priority_queue<node>q;
	rep(i,1,n) d[i]=INF;
	d[s]=0;
	ms0(vis);
	q.push((node){
    
    0,s});
	while(!q.empty()){
    
    
		node x=q.top();q.pop();
		int u=x.p;
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=Fst[u];~i;i=E[i].nxt){
    
    
			int v=E[i].v,w=E[i].w;
			if(d[u]+w<d[v]){
    
    
				d[v]=d[u]+w;
				q.push((node){
    
    d[v],v});
			}
		}
	}
}
void Add(int x,int y,int w){
    
    
	E[++dnt].w=w,E[dnt].u=x,E[dnt].v=y,E[dnt].nxt=Fst[x];
	Fst[x]=dnt;
}
void add(int u,int v,int flow){
    
    
	e[cnt]=(edge){
    
    v,flow,fst[u]};
	fst[u]=cnt++;
	e[cnt]=(edge){
    
    u,0,fst[v]};
	fst[v]=cnt++;
}
bool bfs(int s,int t){
    
    
	ms1(h);
	h[s]=0;
	queue<int>q;
	q.push(s);
	while(!q.empty()){
    
    
		int u=q.front();q.pop();
		for(int i=fst[u];~i;i=e[i].nxt){
    
    
			int v=e[i].v;
			if(e[i].flw&&h[v]==-1){
    
    
				h[v]=h[u]+1;
				q.push(v);
				if(v==t) return 1;
			}
		} 
	}
	return 0;
}
int dfs(int u,int t,int flow){
    
    
	if(u==t) return flow;
	int rst=flow;
	for(int i=fst[u];~i&&rst;i=e[i].nxt){
    
    
		int v=e[i].v;
		if(h[v]==h[u]+1&&e[i].flw){
    
    
			int f=dfs(v,t,min(e[i].flw,rst));
			if(f){
    
    
				e[i].flw-=f;
				e[i^1].flw+=f;
				rst-=f;
			}
			else h[v]=-1;
		}
	}
	return flow-rst;
}
int mflw(int s,int t){
    
    
	int f=0,mxf=0;
	while(bfs(s,t))
		while(f=dfs(s,t,INF))
			mxf+=f;
	return mxf;
}
int main(){
    
    
	int T,s,t;
	Ri(T);
	while(T--){
    
    
		Rii(n,m);
		int u,v,w;
		ms1(fst),ms1(Fst);
		cnt=dnt=0;
		rep(i,1,m){
    
    
			scanf("%d%d%d",&u,&v,&w);
			Add(u,v,w);
		}
		Rii(s,t);
		dij(s,t);
		rep(i,1,m){
    
    
			int u=E[i].u,v=E[i].v;
			if(d[v]==d[u]+E[i].w) add(u,v,1);
		}
		printf("%d\n",mflw(s,t));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u013455437/article/details/111774897