在最大流上加了一个费用
用EK的方法先用spfa找最小费用的一个可行流,在一次次修改,与最大流思想一样,不过找最短路时需要建一个负边#include#include #include #include using namespace std;const int M=199999;int n,m,s,t;int dis[M];;int nex[M],head[M],cos[M],to[M],tot,pre[M],cap[M],vis[M],flo[M],id[M];int add(int x,int y,int z,int w){ cos[tot]=z; cap[tot]=w; nex[++tot]=head[x]; to[tot]=y; head[x]=tot;}int spfa(int s,int t){ queue q; memset(dis,127,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); int INF=dis[0]; dis[s]=0; vis[s]=1; q.push(s); flo[s]=INF; while(!q.empty()){ int x=q.front(); vis[x]=0; q.pop(); for(int i=head[x];i;i=nex[i]) { int tmp=to[i]; if(dis[tmp]>dis[x]+cos[i-1]&&cap[i-1]){ dis[tmp]=dis[x]+cos[i-1]; pre[tmp]=x; flo[tmp]=min(flo[x],cap[i-1]); id[tmp]=i-1; if(!vis[tmp]){ q.push(tmp); vis[tmp]=1; } } } } if(dis[t]>=INF)return 0; return 1; }struct st{ int cost=0; int flow=0;}; st maxflow(int s,int t){ st a; while(spfa(s,t)){ int k=t; while(k!=s){ cap[id[k]]-=flo[t]; cap[id[k]^1]+=flo[t]; k=pre[k]; } a.flow+=flo[t]; a.cost+=flo[t]*dis[t]; } return a;}int main(){ scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++){ int x,y,z,w; scanf("%d%d%d%d",&x,&y,&z,&w); add(x,y,w,z); add(y,x,-w,0); } st d=maxflow(s,t); printf("%d %d",d.flow,d.cost); return 0;}