网络最大流
#include<bits/stdc++.h>
using namespace std;
#define N 1205
#define M 120005
#define int long long
const int inf=1e18;
int n,m,s,t,head,tail,dis[N],q[N*20],k,h[N],he[N],x,y,z;
struct AB{
int a,b,c,n;
}d[M*2];
void cun(int x,int y,int z){d[++k]=(AB){x,y,z,h[x]},h[x]=k;}
void bfs(){
memset(dis,-1,sizeof(dis));
q[head=tail=1]=s,dis[s]=0;
while(head<=tail){
int x=q[head++];
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(d[i].c&&dis[y]==-1){
dis[y]=dis[x]+1;
q[++tail]=y;
}
}
}
}
int dfs(int x,int f){
if(x==t) return f;
int ff=f;
for(int &i=h[x];i;i=d[i].n){//当前弧优化
int y=d[i].b;
if(!d[i].c||dis[y]!=dis[x]+1) continue;
int dick=dfs(y,min(d[i].c,ff));
if(dick){
d[i].c-=dick,d[i^1].c+=dick,ff-=dick;
if(!ff) break;
}
else dis[y]=0;//炸点优化
}
return f-ff;
}
int dinic(){
int ans=0;
while(1){
memcpy(h,he,sizeof(he));
bfs();
if(dis[t]==-1) break;
ans+=dfs(s,inf);
}
return ans;
}
signed main(){
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
k++;
for(int i=1;i<=m;i++){
scanf("%lld%lld%lld",&x,&y,&z);
cun(x,y,z),cun(y,x,0);
}
memcpy(he,h,sizeof(h));
printf("%lld",dinic());
return 0;
}
最小费用最大流
dij
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 5005
#define M 50005
const int inf=1e18;
int n,m,s,t,k,h[N],hh[N],u[N],dis[N],he[N],vis[N],ans1,ans2,x,y,z,zz;
struct AB{
int a,b,c,v,n;
}d[M*2];
void cun(int x,int y,int z,int zz){
d[++k]=(AB){x,y,z,zz,h[x]},h[x]=k;
}
priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > q;
void dij(int x){
memset(u,0,sizeof(u));
memset(dis,9,sizeof(dis));
dis[x]=0,q.push(make_pair(dis[x],x));
while(!q.empty()){
x=q.top().second,q.pop();
if(u[x]) continue;
u[x]=1;
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(d[i].c&&dis[x]+d[i].v+hh[x]-hh[y]<dis[y]){
dis[y]=dis[x]+d[i].v+hh[x]-hh[y];
q.push(make_pair(dis[y],y));
}
}
}
}
int dfs(int x,int f){
if(x==t) return f;
int ff=f;
vis[x]=1;
for(int &i=h[x];i;i=d[i].n){
int y=d[i].b;
if(!d[i].c||dis[y]!=dis[x]+d[i].v+hh[x]-hh[y]||vis[y]) continue;
int dd=dfs(y,min(d[i].c,ff));
if(dd){
d[i].c-=dd,d[i^1].c+=dd,ff-=dd;
if(!ff) break;
}
}
if(f-ff) vis[x]=0;
return f-ff;
}
void mcmf(){
int flag=0;
while(1){
memcpy(h,he,sizeof(h));
dij(s);
if(dis[t]==dis[0]) break;
memset(vis,0,sizeof(vis));
int p=dfs(s,inf);
if(!p) break;
ans1+=p,ans2+=p*(dis[t]+hh[t]);
for(int i=1;i<=n;i++) hh[i]+=dis[i];
}
}
signed main(){
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
k++;
for(int i=1;i<=m;i++){
scanf("%lld%lld%lld%lld",&x,&y,&z,&zz);
cun(x,y,z,zz),cun(y,x,0,-zz);
}
memcpy(he,h,sizeof(h));
mcmf();
printf("%lld %lld",ans1,ans2);
return 0;
}
spfa
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 5005
#define M 50005
int n,m,s,t,ans1,ans2,k;
const int inf=1e18;
int h[N],he[N],dis[N],u[N],vis[N],q[N*20];
struct AB{
int a,b,c,d,n;
}d[M*2];
void cun(int x,int y,int z,int v){
d[++k]=(AB){x,y,z,v,h[x]},h[x]=k;
}
void lian(int x,int y,int z,int v){
cun(x,y,z,v),cun(y,x,0,-v);
}
void spfa(int x){
int head,tail;
memset(dis,127,sizeof(dis));
memset(u,0,sizeof(u));
q[head=tail=1]=x,dis[x]=0,u[x]=1;
while(head<=tail){
x=q[head++],u[x]=0;
for(int i=h[x];i;i=d[i].n){
int y=d[i].b;
if(!d[i].c||dis[y]<=dis[x]+d[i].d) continue;
dis[y]=dis[x]+d[i].d;
if(!u[y]) q[++tail]=y,u[y]=1;
}
}
}
int dfs(int x,int f){
if(x==t) return f;
int ff=f;
vis[x]=1;
for(int &i=h[x];i;i=d[i].n){
int y=d[i].b;
if(!d[i].c||dis[x]+d[i].d!=dis[y]||vis[y]) continue;
int fl=dfs(y,min(ff,d[i].c));
if(fl){
ff-=fl,d[i].c-=fl,d[i^1].c+=fl;
if(!ff) break;
}
}
if(f-ff) vis[x]=0;
return f-ff;
}
void dinic(){
while(1){
memcpy(h,he,sizeof(he));
spfa(s);
if(dis[t]==dis[0]) break;
memset(vis,0,sizeof(vis));
int cnt=dfs(s,inf);
if(!cnt) break;
// printf("%lld\n",cnt);
ans1+=cnt,ans2+=cnt*dis[t];
}
}
signed main(){
k++;
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
for(int i=1,x,y,z,v;i<=m;i++){
scanf("%lld%lld%lld%lld",&x,&y,&z,&v);
lian(x,y,z,v);
}
memcpy(he,h,sizeof(h));
dinic();
printf("%lld %lld",ans1,ans2);
return 0;
}
无源汇上下界可行流
#include<bits/stdc++.h>
using namespace std;
#define N 205
#define M 10205
int n,m,dis[N],h[N],he[N],q[N*20],ru[N],k,sum,ans,head,tail,s,t;
const int inf=1e9;
struct AB{
int a,b,l,h,c,n;
}d[M*2+N*2];
void cun(int a,int b,int c,int dd){d[++k]=(AB){a,b,c,dd,dd-c,h[a]},h[a]=k;}
void bfs(int s){
memset(dis,-1,sizeof(dis));
int x,y;
q[head=tail=1]=s,dis[s]=0;
while(head<=tail){
x=q[head++];
for(int i=he[x];i;i=d[i].n){
y=d[i].b;
if(d[i].c&&dis[y]==-1){
dis[y]=dis[x]+1;
q[++tail]=y;
}
}
}
}
int dfs(int x,int f){
if(x==t) return f;
int ff=f,y,dd;
for(int &i=h[x];i;i=d[i].n){
y=d[i].b;
if(!d[i].c||dis[y]!=dis[x]+1) continue;
dd=dfs(y,min(d[i].c,ff));
if(dd){
d[i].c-=dd,d[i^1].c+=dd,ff-=dd;
if(!ff) break;
}
else dis[y]=0;
}
return f-ff;
}
void dinic(){
while(1){
bfs(s);
if(dis[t]==-1) break ;
memcpy(h,he,sizeof(he));
ans+=dfs(s,inf);
}
}
int main(){
scanf("%d%d",&n,&m);
k=1,s=0,t=n+1;
for(int i=1,a,b,c,d;i<=m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
cun(a,b,c,d),cun(b,a,0,0);
ru[a]-=c,ru[b]+=c;
}
for(int i=1;i<=n;i++){
if(ru[i]>0) cun(s,i,0,ru[i]),cun(i,s,0,0),sum+=ru[i];
if(ru[i]<0) cun(i,t,0,-ru[i]),cun(t,i,0,0);
}
memcpy(he,h,sizeof(h));
dinic();
if(ans!=sum) printf("NO\n");
else{
printf("YES\n");
for(int i=3;i<=m*2+1;i+=2) printf("%d\n",d[i].c+d[i^1].l);
}
return 0;
}
有源汇有上下界最大流
#include<bits/stdc++.h>
using namespace std;
#define N 205
#define M 10205
int n,m,dis[N],h[N],he[N],q[N*20],ru[N],k,sum,ans,head,tail,s,t,ss,tt,ans1;
const int inf=1e9;
struct AB{
int a,b,l,h,c,n;
}d[M*2+N*2];
void cun(int a,int b,int c,int dd){d[++k]=(AB){a,b,c,dd,dd-c,h[a]},h[a]=k;}
void bfs(int s){
memset(dis,-1,sizeof(dis));
int x,y;
q[head=tail=1]=s,dis[s]=0;
while(head<=tail){
x=q[head++];
for(int i=he[x];i;i=d[i].n){
y=d[i].b;
if(d[i].c&&dis[y]==-1){
dis[y]=dis[x]+1;
q[++tail]=y;
}
}
}
}
int dfs(int x,int f){
if(x==t) return f;
int ff=f,y,dd;
for(int &i=h[x];i;i=d[i].n){
y=d[i].b;
if(!d[i].c||dis[y]!=dis[x]+1) continue;
dd=dfs(y,min(d[i].c,ff));
if(dd){
d[i].c-=dd,d[i^1].c+=dd,ff-=dd;
if(!ff) break;
}
else dis[y]=0;
}
return f-ff;
}
void dinic(){
while(1){
bfs(s);
if(dis[t]==-1) break ;
memcpy(h,he,sizeof(he));
ans+=dfs(s,inf);
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&ss,&tt);
k=1,s=0,t=n+1;
for(int i=1,a,b,c,d;i<=m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
cun(a,b,c,d),cun(b,a,0,0);
ru[a]-=c,ru[b]+=c;
}
cun(tt,ss,0,inf),cun(ss,tt,0,0);
for(int i=1;i<=n;i++){
if(ru[i]>0) cun(s,i,0,ru[i]),cun(i,s,0,0),sum+=ru[i];
if(ru[i]<0) cun(i,t,0,-ru[i]),cun(t,i,0,0);
}
memcpy(he,h,sizeof(h));
dinic();
if(ans!=sum) printf("please go home to sleep\n");
else{
ans=0,s=ss,t=tt;
for(int i=h[t];i;i=d[i].n){
if(d[i].b==s){
ans1=d[i^1].c,d[i].c=d[i^1].c=0;
break;
}
}
dinic();
printf("%d\n",ans+ans1);
}
return 0;
}
有源汇有上下界最小流
#include<bits/stdc++.h>
using namespace std;
#define N 500010
#define M 125010
int n,m,dis[N],h[N],he[N],q[N*20],ru[N],k,sum,ans,head,tail,s,t,ss,tt,ans1;
const int inf=1e9;
struct AB{
int a,b,l,h,c,n;
}d[M*2+N*2];
void cun(int a,int b,int c,int dd){d[++k]=(AB){a,b,c,dd,dd-c,h[a]},h[a]=k;}
void bfs(int s){
memset(dis,-1,sizeof(dis));
int x,y;
q[head=tail=1]=s,dis[s]=0;
while(head<=tail){
x=q[head++];
for(int i=he[x];i;i=d[i].n){
y=d[i].b;
if(d[i].c&&dis[y]==-1){
dis[y]=dis[x]+1;
q[++tail]=y;
}
}
}
}
int dfs(int x,int f){
if(x==t) return f;
int ff=f,y,dd;
for(int &i=h[x];i;i=d[i].n){
y=d[i].b;
if(!d[i].c||dis[y]!=dis[x]+1) continue;
dd=dfs(y,min(d[i].c,ff));
if(dd){
d[i].c-=dd,d[i^1].c+=dd,ff-=dd;
if(!ff) break;
}
else dis[y]=0;
}
return f-ff;
}
void dinic(){
while(1){
bfs(s);
if(dis[t]==-1) break ;
memcpy(h,he,sizeof(he));
ans+=dfs(s,inf);
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&ss,&tt);
k=1,s=0,t=n+1;
for(int i=1,a,b,c,d;i<=m;i++){
scanf("%d%d%d%d",&a,&b,&c,&d);
cun(a,b,c,d),cun(b,a,0,0);
ru[a]-=c,ru[b]+=c;
}
cun(tt,ss,0,inf),cun(ss,tt,0,0);
for(int i=1;i<=n;i++){
if(ru[i]>0) cun(s,i,0,ru[i]),cun(i,s,0,0),sum+=ru[i];
if(ru[i]<0) cun(i,t,0,-ru[i]),cun(t,i,0,0);
}
memcpy(he,h,sizeof(h));
dinic();
if(ans!=sum) printf("please go home to sleep\n");
else{
ans=0,s=ss,t=tt;
for(int i=h[t];i;i=d[i].n){
if(d[i].b==s){
ans1=d[i^1].c,d[i].c=d[i^1].c=0;
break;
}
}
s=tt,t=ss;
dinic();
printf("%d\n",ans1-ans);
}
return 0;
}