網絡流

最大流

學習鏈接

學習鏈接2

模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
template<class T>inline void MAX(T &x,T y){if(y>x)x=y;}
template<class T>inline void MIN(T &x,T y){if(y<x)x=y;}
template<class T>inline void rd(T &x){
	x=0;char o,f=1;
	while(o=getchar(),o<48)if(o==45)f=-f;
	do x=(x<<3)+(x<<1)+(o^48);
	while(o=getchar(),o>47);
	x*=f;
}
const int M=1e5+5;
const int inf=1e9;
int n,m,s,t,tot,head[M],to[M<<1],nxt[M<<1],flow[M<<1];
inline void add_edge(int a,int b,int c){
	to[++tot]=b;
	flow[tot]=c;
	nxt[tot]=head[a];
	head[a]=tot;
}
int Q[M],deep[M],cur[M];
bool BFS(){
	for(int i=1;i<=n;i++)deep[i]=-1;
	for(int i=1;i<=n;i++)cur[i]=head[i];
	int L=0,R=0;
	deep[s]=0;
	Q[++R]=s;
	while(L<R){
		int x=Q[++L];
		for(int i=head[x];i;i=nxt[i]){
			int y=to[i];
			if(deep[y]==-1&&flow[i]>0){
				deep[y]=deep[x]+1;
				Q[++R]=y;
			}
		}
	}
	return deep[t]!=-1;
}
int dfs(int x,int limit){
	if(x==t||!limit)return limit;
	int mxflow=0;
	for(int &i=cur[x];i;i=nxt[i]){
		int y=to[i];
		if(deep[y]==deep[x]+1){
			int f=dfs(y,min(limit,flow[i]));
			if(!f)continue;
			mxflow+=f;
			limit-=f;
			flow[i]-=f;
			flow[i^1]+=f;
			if(!limit)break;
		}
	}
	return mxflow;
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("jiedai.in","r",stdin);
//  freopen("jiedai.out","w",stdout);
#endif
	memset(head,0,sizeof(head));
	tot=1;
	rd(n),rd(m),rd(s),rd(t);
	for(int i=1;i<=m;i++){
		int a,b,c;
		rd(a),rd(b),rd(c);
		add_edge(a,b,c);
		add_edge(b,a,0);
	}
	int ans=0;
	while(BFS())ans+=dfs(s,inf);
	printf("%d\n",ans);
	return (0-0);
}

費用流(最小費用最大流)

學習鏈接

模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
template<class T>inline void MAX(T &x,T y){if(y>x)x=y;}
template<class T>inline void MIN(T &x,T y){if(y<x)x=y;}
template<class T>inline void rd(T &x){
	x=0;char o,f=1;
	while(o=getchar(),o<48)if(o==45)f=-f;
	do x=(x<<3)+(x<<1)+(o^48);
	while(o=getchar(),o>47);
	x*=f;
}
const int M=4e5+5;
const ll INF=1e18;
const int inf=1e9;
int n,m,s,t,tot,head[M],to[M<<1],nxt[M<<1],flow[M<<1],cost[M<<1];
void add_edge(int a,int b,int c,int d){
	to[++tot]=b;
	flow[tot]=c;
	cost[tot]=d;
	nxt[tot]=head[a];
	head[a]=tot;
}
int Q[M],limit[M],mark[M],pre[M],last[M];
ll dis[M],mxflow,micost;
bool SPFA(){
	for(int i=1;i<=n;i++)dis[i]=INF,limit[i]=inf,mark[i]=0;
	int L=0,R=0;
	Q[++R]=s;
	dis[s]=0;
	pre[t]=0;
	while(L!=R){
		int x=Q[L=L%n+1];
		mark[x]=0;
		for(int i=head[x];i;i=nxt[i]){
			int y=to[i];
			if(flow[i]&&dis[x]+cost[i]<dis[y]){
				dis[y]=dis[x]+cost[i];
				pre[y]=x;
				last[y]=i;
				limit[y]=min(limit[x],flow[i]);
				if(!mark[y]){
					Q[R=R%n+1]=y;
					mark[y]=1;
				}
			}
		}
	}
	return pre[t];
}
void MCMF(){
	while(SPFA()){
		mxflow+=limit[t];
		micost+=limit[t]*dis[t];
		for(int i=t;i!=s;i=pre[i]){
			flow[last[i]]-=limit[t];
			flow[last[i]^1]+=limit[t];
		}
	}
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("jiedai.in","r",stdin);
//  freopen("jiedai.out","w",stdout);
#endif
	memset(head,0,sizeof(head));
	tot=1;
	rd(n),rd(m),rd(s),rd(t);
	for(int i=1;i<=m;i++){
		int a,b,c,d;
		rd(a),rd(b),rd(c),rd(d);
		add_edge(a,b,c,d);
		add_edge(b,a,0,-d);
	}
	MCMF();
	printf("%lld %lld\n",mxflow,micost);
	return (0-0);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章