struct costFlow{//邻接表
typedef int type;
struct edge{
int from,to;
type flow,cost;
edge(int u=0,int v=0,type f=0,type c=0){
from=u,to=v,flow=f,cost=c;
}
};
vector<edge>edg; //边表
vector<int>g[M]; //邻接表
int n,m; //顶点数,边数
int inq[M],dis[M];//是否在队列中,距离起点的距离
int pre[M],aug[M];//上一条弧,可改进量
void init(int _n){
n=_n,edg.clear();
for(int i=0;i<n;i++) g[i].clear();
}
void insert(int u,int v,type f,type c){
edg.push_back(edge(u,v,f,c)),edg.push_back(edge(v,u,0,-c));
m=edg.size();
g[u].push_back(m-2),g[v].push_back(m-1);
}
bool spfa(int s,int t,type& flow,type& cost){
for(int i=0;i<n;i++) dis[i]=INF;
clr(inq,0,n);
dis[s]=0,inq[s]=1,pre[s]=0,aug[s]=INF;
queue<int>q;
for(q.push(s);!q.empty();){
int u=q.front();q.pop();inq[u]=0;
for(int i=0;i<g[u].size();i++){
edge& e=edg[g[u][i]];
if(e.flow>0 && dis[e.to]>dis[u]+e.cost){
dis[e.to]=dis[u]+e.cost;
pre[e.to]=g[u][i];
aug[e.to]=_min(aug[u],e.flow);
if(!inq[e.to]) q.push(e.to),inq[e.to]=1;
}
}
}
if(dis[t]==INF) return false;
flow+=aug[t],cost+=aug[t]*dis[t];
for(int u=t;u!=s;u=edg[pre[u]].from){
edg[pre[u]].flow-=aug[t];
edg[pre[u]^1].flow+=aug[t];
}
return true;
}
type minCost(int s,int t){
type flow=0,cost=0;
while(spfa(s,t,flow,cost));
return cost;
}
}p;