裸最小费用最大流问题
#include<cstdio>
#include<queue>
#include<cstring>
const int N=1000+10,M=10000+10;
using namespace std;
queue<int> q;
int head[M << 2],nxt[M << 2],to[M << 2],val[M << 2],flt[M << 2];
int dis[N],pree[N],pred[N],cn;
int n,m,u,v,c,tmp,src,sink,delta,inf=1e8,maxcost;
bool vis[N];
inline void read( int&x ) {
int f=1;x=0;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=10*x+c-48,c=getchar();
x=x*f;
}
void create(int u,int v,int f,int w){
cn++;
to[cn]=v;
flt[cn]=f;
val[cn]=w;
nxt[cn]=head[u];
head[u]=cn;
cn++;
to[cn]=u;
flt[cn]=0;
val[cn]=-w;
nxt[cn]=head[v];
head[v]=cn;
}
bool spfa(){
int j;
memset(dis,0x7f,sizeof(dis));
memset(vis,false,sizeof(vis));
while(!q.empty()) q.pop();
vis[src]=true;
q.push(src);
dis[src]=0;
while(!q.empty()){
tmp=q.front();
for(int i=head[tmp];i;i=nxt[i]){
j=to[i];
if(flt[i] && dis[tmp]+val[i]<dis[j]){
dis[j]=dis[tmp]+val[i];
pred[j]=tmp;
pree[j]=i;
if(!vis[j]){
q.push(j);
vis[j]=true;
}
}
}
vis[tmp]=false;
q.pop();
}
return dis[sink]<inf;
}
void augment_path(){
u=sink;
delta=inf;
while(u!=src){
if(flt[pree[u]]<delta)
delta=flt[pree[u]];
u=pred[u];
}
u=sink;
while(u!=src){
flt[pree[u]]-=delta;
flt[pree[u]^1]+=delta;
u=pred[u];
}
maxcost+=delta * dis[sink];
}
int main(){
read(n);read(m);
cn=1;
create(0,1,2,0);
create(1,0,2,0);
for(int i=1;i<=m;i++){
read(u);read(v);read(c);
create(u,v,1,c);
create(v,u,1,c);
}
create(n,n+1,2,0);
create(n+1,n,2,0);
src=0;sink=n+1;
while(spfa())
augment_path();
printf("%d",maxcost);
return 0;
}