dinic最大流:
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i = (int)a;i<=(int)b;i++)
#define pb push_back
#define lson rt<<1
#define rson rt<<1|1
#define mid (l+r)/2
using namespace std;
const int maxn=200005;
const int maxm=2000005;
const int MAX = 1<<26;
typedef long long ll;
typedef pair<int,int> pii;
int nex[maxm],to[maxm],cap[maxm],from[maxm];
int n,m,cnt,head[maxn],d[maxn],sp,tp;//原点,汇点
//理论复杂度n2*m
void add(int u,int v,int c){
from[cnt]=u,to[cnt]=v,cap[cnt]=c,nex[cnt]=head[u],head[u]=cnt++;
from[cnt]=v,to[cnt]=u,cap[cnt]=0,nex[cnt]=head[v],head[v]=cnt++;
}
int bfs(){
queue <int> q;
memset(d,-1,sizeof(d));
d[sp]=0;
q.push(sp);
while(!q.empty()){
int cur=q.front();
q.pop();
for(int i=head[cur];i!=-1;i=nex[i]){
int u=to[i];
if(d[u]==-1 && cap[i]>0){
d[u]=d[cur]+1;
q.push(u);
}
}
}
return d[tp] != -1;
}
int dfs(int a,int b){
int r=0;
if(a==tp)return b;
for(int i=head[a];i!=-1 && r<b;i=nex[i])
{
int u=to[i];
if(cap[i]>0 && d[u]==d[a]+1)
{
int x=min(cap[i],b-r);
x=dfs(u,x);
r+=x;
cap[i]-=x;
cap[i^1]+=x;
}
}
if(!r)d[a]=-2;
return r;
}
int dinic(int sp,int tp){
int total=0,t;
while(bfs()){
while(t=dfs(sp,MAX))
total+=t;
}
return total;
}
int main(){
int i,u,v,c,x;
cnt=0;
memset(head,-1,sizeof(head));
return 0;
}
一个封装好了的版本
struct Dinic{
const int MAX=1<<26;
int head[maxn],nex[maxm],cap[maxm],to[maxm],cnt,n;
void add_edge(int u,int v,int c){
to[cnt]=v,nex[cnt]=head[u],cap[cnt]=c,head[u]=cnt++;
}
void add(int u,int v,int c){
add_edge(u,v,c); add_edge(v,u,0);
}
void init(int nn,int ssp,int ttp){
n=nn; cnt=0; sp=ssp,tp=ttp;
memset(head,-1,sizeof(head));
}
int sp,tp,dis[maxn];
int bfs(){
queue<int> q;
memset(dis,-1,sizeof(dis));
dis[sp]=0;
q.push(sp);
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=head[u];~i;i=nex[i]){
int v=to[i];
if(dis[v]==-1 && cap[i]>0){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[tp] != -1;
}
int dfs(int u,int c){
int r=0;
if(u==tp) return c;
for(int i=head[u];~i;i=nex[i]){
int v=to[i];
if(cap[i]>0&&dis[v]==dis[u]+1){
int x=min(cap[i],c-r);
x=dfs(v,x);
r+=x;
cap[i]-=x;
cap[i^1]+=x;
}
}
if(!r) dis[u]=-2;
return r;
}
int dinic(){
int tot=0,t;
while(bfs()){
while(t=dfs(sp,MAX))
tot+=t;
}
return tot;
}
} D;
EK费用流
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = (int)a;i<=(int)b;i++)
using namespace std;
typedef long long ll;
const int maxn=400000;
const int maxm=1000000;
const int inf=0x3f3f3f3f;
int dis[maxn];
int vis[maxn],pre[maxn];
int head[maxn],cnt;
int n,m,sp,tp;
ll ans=0;
struct node{
int to,cap,cost,next;
}e[maxm];
void add(int from,int to,int cap,int cost){
e[cnt].to=to; e[cnt].cap=cap;
e[cnt].cost=cost; e[cnt].next=head[from];
head[from]=cnt++;
e[cnt].to=from; e[cnt].cap=0;
e[cnt].cost=-cost; e[cnt].next=head[to];
head[to]=cnt++;
}
bool spfa(int s,int t,int &flow,int &cost){
queue<int> q;
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
dis[s]=0; q.push(s);
vis[s]=1;
int d=inf;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(e[i].cap>0&&dis[v]>dis[u]+e[i].cost){
dis[v]=dis[u]+e[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
if(dis[t]==inf){
return false;
}
for(int i=pre[t];~i;i=pre[e[i^1].to]){
d=min(d,e[i].cap);
}
for(int i=pre[t];~i;i=pre[e[i^1].to]){
e[i].cap-=d;
e[i^1].cap+=d;
cost+=e[i].cost*d;
}
flow+=d;
return true;
}
int mcmf(int s,int t){
int flow=0,cost=0;
while(spfa(s,t,flow,cost)){
//cout<<flow<<" "<<cost<<endl;
}
return cost;
}
int main(){
memset(head,-1,sizeof(head));
ans=0;
scanf("%d",&n);
sp=0;tp=50001;
cout<<mcmf(sp,tp)<<endl;
return 0;
}
不出意外的dijkstra模板(EK)
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = (int)a;i<=(int)b;i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=400000;
const int maxm=1000000;
const int inf=0x3f3f3f3f;
int dis[maxn];
int vis[maxn],pre[maxn];
int head[maxn],cnt,h[maxn],tmpc[maxn];
int to[maxm],cap[maxm],cost[maxm],nex[maxm];
int n,m,sp,tp;
ll ans=0;
struct node{
int dis,id;
node(){}
node(int id,int dis):id(id),dis(dis){}
bool operator < (const node &a)const{
return dis>a.dis;
}
};
void add(int ffrom,int tto,int ccap,int ccost){
to[cnt]=tto; cap[cnt]=ccap;
cost[cnt]=ccost; nex[cnt]=head[ffrom];
head[ffrom]=cnt++;
to[cnt]=ffrom; cap[cnt]=0;
cost[cnt]=-ccost; nex[cnt]=head[tto];
head[tto]=cnt++;
}
bool Dijkstra(int s,int t,int &flow,int &tmpcost,int n){
priority_queue<pii ,vector<pii> ,greater<pii> > Q;
for(int i=1;i<=n;i++){
dis[i]=inf;
vis[i]=0;
pre[i]=-1;
}
dis[s]=0; Q.push({0,s});
vis[s]=1; tmpc[s]=inf;
while(!Q.empty()){
pii tmp= Q.top(); Q.pop();
int u=tmp.second;
if(dis[u]<tmp.first) continue;
for(int i=head[u];~i;i=nex[i]){
int v=to[i];
if(cap[i]>0&&dis[v]>dis[u]+cost[i]+h[u]-h[v]){
dis[v]=dis[u]+cost[i]+h[u]-h[v];
pre[v]=i; tmpc[v]=min(cap[i],tmpc[u]);
Q.push({dis[v],v});
}
}
}
if(dis[t]==inf){
return false;
}
for(int i=1;i<=n;i++){
if(dis[i]<inf) h[i]+=dis[i];
}
int d=tmpc[t];
for(int i=pre[t];~i;i=pre[to[i^1]]){
cap[i]-=d;
cap[i^1]+=d;
}
flow+=d;
tmpcost+=h[t]*d;
return true;
}
int mcmf(int s,int t,int nn){
int flow=0,cost=0;
while(Dijkstra(s,t,flow,cost,nn)){
//cout<<flow<<" "<<cost<<endl;
}
return cost;
}
int main(){
memset(head,-1,sizeof(head));
ans=0;
scanf("%d",&n);
sp=0;tp=50001;
cout<<mcmf(sp,tp,n)<<endl;
return 0;
}
zkw费用流
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = (int)a;i<=(int)b;i++)
#define rep_e(i,u,v) for(int i=head[u],v=to[i];~i;i=nex[i],v=to[i])
using namespace std;
typedef long long ll;
const int maxn=100005;
const int maxm=200005;
const int inf=1e9+7;
bool vis[maxn];
int dist[maxn],sp,tp,n,m;
int head[maxn],to[maxm],nex[maxm],cap[maxm],cost[maxm],cnt;
void add(int u,int v,int Cap,int Cost){
to[cnt]=v; nex[cnt]=head[u]; cap[cnt]=Cap; cost[cnt]=Cost; head[u]=cnt++;
to[cnt]=u; nex[cnt]=head[v]; cap[cnt]=0; cost[cnt]=-Cost; head[v]=cnt++;
}
inline bool Spfa(int s,int t){
memset(vis,0,sizeof(vis));
rep(i,0,n){
dist[i]=inf;
}
dist[t]=0,vis[t]=1;
deque<int> q;
q.push_back(t);
while(!q.empty()){
int u=q.front(); q.pop_front();
for(int i=head[u];~i;i=nex[i]){
int v=to[i];
if(cap[i^1]&&dist[v]>dist[u]-cost[i]){
dist[v]=dist[u]-cost[i];
if(!vis[v]){
vis[v]=1;
if(!q.empty()&&dist[v]<dist[q.front()])
q.push_front(v);
else q.push_back(v);
}
}
}
vis[u]=0;
}
return dist[s]<inf;
}
inline int dfs(int u,int low,int &Cost){
if(u==tp){
vis[tp]=1;
return low;
}
int used=0,flow;
vis[u]=1;
for(int i=head[u];~i;i=nex[i]){
int v=to[i];
if(!vis[v]&&cap[i]&&dist[u]-cost[i]==dist[v]){
flow=dfs(v,min(cap[i],low-used),Cost);
if(flow) {
Cost+=flow*cost[i];
cap[i]-=flow; cap[i^1]+=flow;
used+=flow;
}
if(used==low) break;
}
}
return used;
}
inline int mcmf(int sp,int tp,int &flow){
flow=0;
int Cost=0;
while(Spfa(sp,tp)){
vis[tp]=1;
while(vis[tp]){
memset(vis,0,sizeof(vis));
flow+=dfs(sp,inf,Cost);
}
}
return Cost;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d%d%d",&n,&m,&sp,&tp);
rep(i,1,m){
int u,v,ca,co; scanf("%d%d%d%d",&u,&v,&ca,&co);
add(u,v,ca,co);
}
int flow;
int costs=mcmf(sp,tp,flow);
printf("%d %d\n",flow,costs);
return 0;
}