P3381 落谷 最小费用最大流

https://www.luogu.org/problem/P3381

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define  inf 100010
using namespace std;

int point[2*inf],next1[2*inf],first[2*inf],cap[2*inf],cost[2*inf];
bool vis[inf];
int pre[inf],path[inf],dis[inf];
//pre[i] 表示 i号节点 的前驱节点
//path[i] 表示 i号节点 的前驱边
int n,m,s,t,min_cost,max_flow,k;

void edge(int,int,int,int);
int MinCostMaxFlow(int,int);
bool SPFA(int,int);
queue<int>q;
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    memset(first,0xff, sizeof(first));
    for(int i = 1; i <= m; i++)
    {
        int u,v,w,f;

        scanf("%d%d%d%d",&u,&v,&w,&f);
        edge(u,v,w,f);//有向边建边一次
    }
    MinCostMaxFlow(s,t);
    printf("%d %d",max_flow,min_cost);
}
bool SPFA(int s,int t)
{
   memset(dis,0x7f, sizeof(dis));//10亿+
   memset(pre,0xff, sizeof(pre));//-1
   memset(vis, false, sizeof(vis));

   dis[s] = 0;
   vis[s] = true;
   q.push(s);
   while(!q.empty())
   {
       int now = q.front();
       q.pop();
       vis[now] = false;
       for(int k = first[now];k != -1;k = next1[k])
       {
           int new1 = point[k];
           if(cap[k] > 0 && dis[now] + cost[k] < dis[new1])
           {
               dis[new1] = dis[now] + cost[k];
               pre[new1] = now;
               path[new1] = k;
               if(!vis[new1]) vis[new1] = true,q.push(new1);
           }
       }
   }
   if(pre[t] == -1) return false;
   return true;
}
int MinCostMaxFlow(int s,int t)
{
    min_cost = 0,max_flow = 0;
   while(SPFA(s,t))
   {
       int mi = 1e9;
       for(int i = t;i != s;i = pre[i])
       {
           if(cap[path[i]] < mi)
               mi = cap[path[i]];
       }
       max_flow += mi;
       min_cost += dis[t]*mi;
       for(int i = t;i != s;i = pre[i]){
           cap[path[i]] -= mi;
           cap[path[i]^1] += mi;//用异或快很多!!! 不要奇偶性!!!
       }
   }
}
void edge(int u,int v,int w,int f)//建边 从 0号 开始建边
{
    point[k] = v;next1[k] = first[u];first[u] = k;
    cap[k] = w;cost[k++] = f;

    point[k] = u;next1[k] = first[v];first[v] = k;
    cap[k] = 0;cost[k++] = -f;
}

猜你喜欢

转载自blog.csdn.net/weixin_43912833/article/details/99111989
今日推荐