• 网络流 最小费用最大流


    //EK 最小费用最大流 
    //只需将最大流中的bfs改为SPFA即可 
    //注意 若要跑最大费用最大流 只需在加边时将正反边费用分别取反
    //跑完最小费用最大流后把mincost取反即可
    #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<queue> #define ll long long #define ull unsigned long long #define INF 0x3f3f3f3f using namespace std; int n,m,s,t,maxflow,mincost,cnt=-1; int head[5001],pre[5001],mflow[5001],mcost[5001],vis[5001]; //pre最短路上每个点所连的前一条边 mflow源点到每个点的最大增量 mcost源点到每个点的最小费用 vis为SPFA数组 struct uio{ int to,nxt,flow,cost; }edge[100001]; void add(int x,int y,int f,int c) { edge[++cnt].nxt=head[x]; edge[cnt].to=y; edge[cnt].flow=f; edge[cnt].cost=c; head[x]=cnt; } bool spfa() { memset(mflow,0x3f,sizeof(mflow)); memset(mcost,0x3f,sizeof(mcost)); memset(vis,0,sizeof(vis)); queue<int> que; que.push(s); mcost[s]=0; pre[t]=-1; vis[s]=1; while(!que.empty()) { int now=que.front(); que.pop(); vis[now]=0; for(int i=head[now];i!=-1;i=edge[i].nxt) { int y=edge[i].to; if(edge[i].flow>0&&mcost[y]>mcost[now]+edge[i].cost)//是正边 { mcost[y]=mcost[now]+edge[i].cost; pre[y]=i; mflow[y]=min(mflow[now],edge[i].flow); if(!vis[y]) { vis[y]=1; que.push(y); } } } } return pre[t]!=-1;//若能增广到汇点 则其前一条边就会有标记 } void EK() { while(spfa()) { int now=t; maxflow+=mflow[t]; mincost+=mcost[t]*mflow[t]; while(now!=s)//一直回溯到源点 { edge[pre[now]].flow-=mflow[t]; edge[pre[now]^1].flow+=mflow[t]; now=edge[pre[now]^1].to; } } } int main() { memset(head,-1,sizeof(head)); scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++) { int u,v,w,p; scanf("%d%d%d%d",&u,&v,&w,&p); add(u,v,w,p); add(v,u,0,-p); } EK(); printf("%d %d ",maxflow,mincost); return 0; }
  • 相关阅读:
    Send or receive files via Xshell
    git archive命令详解
    test命令详解
    shell中的数学运算
    深入理解文件权限
    rebuild online时意外中断 再次重建时报错解决方法
    关于临时表空间,在日常生产中会遇到的问题
    Oracle对于敏感数据的处理,可以采用策略(dbms_rls.add_policy)
    我对于B-树索引的内部结构与索引类型所做的笔记
    记一次ADG备库归档目录满导致的延时处理
  • 原文地址:https://www.cnblogs.com/water-radish/p/9280670.html
Copyright © 2020-2023  润新知