网络流 学习笔记
最大流
略。
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:网流之神的传奇一生