网络流 学习笔记

最大流

略。

update:我发现我的最大流一直是写错的!!写错一年了!!这一年居然没有被卡真是奇迹……

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define mar(o) for(int E=fst[o];E;E=e[E].nxt)
#define marz(o) for(int E=fstz[o];E;E=e[E].nxt)
#define v e[E].to
#define lon long long
using namespace std;
const int n7=101234,m7=201234;
const lon inf=1e8;
struct dino{int to,nxt;lon w;}e[m7];
int ds,dt,n,m,ecnt=1,fst[n7],fstz[n7],dep[n7],head,tail,que[n7];

int rd(){
	int shu=0;bool fu=0;char ch=getchar();
	while( !isdigit(ch) ){if(ch=='-')fu=1;ch=getchar();}
	while( isdigit(ch) )shu=(shu<<1)+(shu<<3)+ch-'0',ch=getchar();
	return fu?-shu:shu;
}

void Dedge(int p,int q,int w){
	ecnt++;
	e[ecnt]=(dino){q,fst[p],w};
	fst[p]=ecnt;
}

void edge(int p,int q,int w){
	Dedge(p,q,w),Dedge(q,p,0);
}

bool bfs(){
	rep(i,1,n+n+2)dep[i]=0;
	head=tail=1,que[1]=ds,dep[ds]=1,fstz[ds]=fst[ds];
	while(head<=tail){
		int o=que[head];++head;
		mar(o){
			if(dep[v]||!e[E].w)continue;
			dep[v]=dep[o]+1,fstz[v]=fst[v];
			if(v==dt)return 1;
			tail++,que[tail]=v;
		}
	}
	return 0;
}

int dfs(int o,int val){
	if(o==dt)return val;
	int res=val;
	marz(o){
		if(!res)break;
		fstz[o]=E;
		if(dep[v]!=dep[o]+1||!e[E].w)continue;
		int out=dfs(v, min(e[E].w,res) );
		e[E].w-=out,e[E^1].w+=out,res-=out;	
	}
	return val-res;
}

int mflow(){
	int tot=0;
	while( bfs() )tot+=dfs(ds,inf);
	return tot;
}

int main(){
	n=rd(),m=rd(),ds=rd(),dt=rd();
	rep(i,1,m){
		int p=rd(),q=rd();lon w=rd();
		edge(p,q,w);
	}
	printf("%lld", mflow() );
	return 0;
}

费用流

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define per(i,x,y) for(int i=x;i>=y;--i)
#define mar(o) for(int E=fst[o],v=e[E].to;E;E=e[E].nxt,v=e[E].to)
#define lon long long
using namespace std;
mt19937 rng( time(0) );
const int n7=101234,m7=201234;
struct dino{int to,nxt,w,c;}e[m7];
int n,m,ds,dt,ecnt=1,fst[n7],dis[n7],inq[n7],head,tail,que[n7],dlas[n7],elas[n7];

int rd(){
	int shu=0;bool fu=0;char ch=getchar();
	while( !isdigit(ch) ){if(ch=='-')fu=1;ch=getchar();}
	while( isdigit(ch) )shu=(shu<<1)+(shu<<3)+ch-'0',ch=getchar();
	return fu?-shu:shu;
}

void Dedge(int p,int q,int w,int c){
	ecnt++;
	e[ecnt]=(dino){q,fst[p],w,c};
	fst[p]=ecnt;
}

void edge(int p,int q,int w,int c){
	Dedge(p,q,w,c),Dedge(q,p,0,-c);
}

void slf(){
	if(dis[ que[head] ]>dis[ que[tail] ])swap(que[head],que[tail]);
}

bool spfa(){
	memset(inq,0,sizeof inq);
	memset(dis,0x3f,sizeof dis),dis[ds]=0;
	head=tail=1,que[1]=ds,inq[ds]=1;
	while(head<=tail){
		int o=que[head];
		inq[o]=0,++head,slf();
		mar(o){
			if(e[E].w&&dis[v]>dis[o]+e[E].c){
				dis[v]=dis[o]+e[E].c;
				dlas[v]=o,elas[v]=E;
				if(!inq[v])tail++,que[tail]=v,slf(),inq[v]=1;
			}
		}
	}
	return dis[dt]<dis[0];
}

pair <int,int> work(){
	int mni=INT_MAX,tot=0;
	for(int o=dt;o^ds;o=dlas[o])mni=min(mni,e[ elas[o] ].w);
	for(int o=dt;o^ds;o=dlas[o]){
		e[ elas[o] ].w-=mni,e[ elas[o]^1 ].w+=mni;
		tot+=mni*e[ elas[o] ].c;
	}
	return make_pair(mni,tot);
}

pair <int,int> SSP(){
	int tot1=0,tot2=0;
	while( spfa() ){
		auto t=work();
		tot1+=t.first,tot2+=t.second;
	}
	return make_pair(tot1,tot2);
}

int main(){
	n=rd(),m=rd(),ds=rd(),dt=rd();
	rep(i,1,m){
		int p=rd(),q=rd(),w=rd(),c=rd();
		edge(p,q,w,c);
	}
	auto t=SSP();
	printf("%d %d\n",t.first,t.second);
	return 0;
}

无源汇上下界可行流等等

见我博客 WR:网流之神的传奇一生

posted @ 2021-02-09 19:50  BlankAo  阅读(58)  评论(0编辑  收藏  举报