模板—费用流(最小费用最大流)
模板—费用流(最小费用最大流)
Code:
#include <queue> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define inf 1000000000 #define N 100010 #define M 1000010 int idx=1,n,m,s,t,ans,dist[N]; bool vis[N]; int head[N],to[M<<2],val[M<<2],cost[M<<2],nxt[M<<2]; void add(int a,int b,int c,int d) {nxt[++idx]=head[a],to[idx]=b,val[idx]=c,cost[idx]=d,head[a]=idx;} bool spfa(int s,int t) { memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) dist[i]=inf; dist[t]=0,vis[t]=1; deque <int> q; q.push_back(t); while(!q.empty()) { int p=q.front(); q.pop_front(); for(int i=head[p];i;i=nxt[i]) if(val[i^1]&&dist[to[i]]>dist[p]-cost[i]) { dist[to[i]]=dist[p]-cost[i]; if(!vis[to[i]]) { vis[to[i]]=true; if((!q.empty())&&dist[to[i]]<dist[q.front()]) q.push_front(to[i]); else q.push_back(to[i]); } } vis[p]=false; } return dist[s]<inf; } int dfs(int p,int flow) { int temp=flow,now; vis[p]=true; if(p==t) return flow; for(int i=head[p];i;i=nxt[i]) if((!vis[to[i]])&&val[i]&&dist[p]-cost[i]==dist[to[i]]) { now=dfs(to[i],min(temp,val[i])); if(now) ans+=now*cost[i],val[i]-=now,val[i^1]+=now,temp-=now; if(!temp) break; } return flow-temp; } int costflow() { int flow=0; while(spfa(s,t)) { vis[t]=true; while(vis[t]) memset(vis,0,sizeof vis),flow+=dfs(s,inf); } return flow; } int main() { scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1,a,b,c,d;i<=m;i++) scanf("%d%d%d%d",&a,&b,&c,&d),add(a,b,c,d),add(b,a,0,-d); printf("%d ",costflow()),printf("%d\n",ans); }