bzoj1834:最大流+最小费用最大流

为什么昨天看的时候就一直看不懂,果然智商是硬伤。。。然后今晚一看就懂了OrzOrz,关键是限制容量那个技巧。。。

--------------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
const int inf=0x3f3f3f3f;
int read(){
 int x=0;char c=getchar();
 while(!isdigit(c))c=getchar();
 while(isdigit(c)){
  x=x*10+c-‘0‘;
  c=getchar();
 }
 return x;
}

struct edge{
 int to,cap,cost;
 edge *next,*rev;
};
edge e[20005],*pt=e,*cur[1005],*p[1005],*head[1005];
int d[1005],cnt[1005],inq[1005],a[1005];
void add(int u,int v,int d,int w){
 pt->to=v;pt->cap=d;pt->cost=w;pt->next=head[u];head[u]=pt++;
}
void adde(int u,int v,int d,int w){
 add(u,v,d,w);add(v,u,0,-w);
 head[u]->rev=head[v];
 head[v]->rev=head[u];
}
struct Edge{
 int from,to,cap,cost;
}edges[5005];

int maxflow(int s,int t,int n){
 clr(d,0);clr(cnt,0);cnt[0]=n;
 int flow=0,a=inf,x=s;
 while(d[s]<n){
  edge *ee;
  for(ee=cur[x];ee;ee=ee->next)
    if(ee->cap>0&&d[ee->to]+1==d[x]) break;
  if(ee){
   p[ee->to]=cur[x]=ee;
   a=min(a,ee->cap);
   x=ee->to;
   if(x==t){
    while(x!=s){
     p[x]->cap-=a;
     p[x]->rev->cap+=a;
     x=p[x]->rev->to;
    }
    flow+=a;
    a=inf;
   }
  }else{
   if(!--cnt[d[x]]) break;
   d[x]=n;
   for(ee=head[x];ee;ee=ee->next){
    if(ee->cap>0&&d[ee->to]+1<d[x]){
     d[x]=d[ee->to]+1;
     cur[x]=ee;
    }
   }
   cnt[d[x]]++;
   if(x!=s) x=p[x]->rev->to;
  }
 }
 return flow;
}

int mincost(int s,int t){
 int cost=0;
 while(1){
  clr(d,inf);clr(inq,0);
  d[s]=0;a[s]=inf;
  queue<int>q;q.push(s);inq[s]=1;
  while(!q.empty()){
   int x=q.front();q.pop();inq[x]=0;
   for(edge *ee=head[x];ee;ee=ee->next){
    if(ee->cap>0&&d[x]+ee->cost<d[ee->to]){
     d[ee->to]=d[x]+ee->cost;
     p[ee->to]=ee;
     a[ee->to]=min(a[x],ee->cap);
     if(!inq[ee->to]){
      q.push(ee->to);inq[ee->to]=1;
     }
    }
   }
  }
  if(d[t]==inf) break;
  cost+=a[t]*d[t];
  int x=t;
  while(x!=s){
   p[x]->cap-=a[t];
   p[x]->rev->cap+=a[t];
   x=p[x]->rev->to;
  }
 }
 return cost;
}

int main(){
 int n=read(),m=read(),k=read();
 rep(i,m){
  Edge &o=edges[i];
  o.from=read(),o.to=read(),o.cap=read(),o.cost=read();
  adde(o.from,o.to,o.cap,0);
 }
 int s=1,t=n;
 printf("%d ",maxflow(s,t,n));
 rep(i,m){
  Edge &o=edges[i];
  adde(o.from,o.to,inf,o.cost);
 }
 adde(0,s,k,0);adde(t,n+1,k,0);
 printf("%d\n",mincost(0,n+1));
 return 0;
}

--------------------------------------------------------------------------------------------

1834: [ZJOI2010]network 网络扩容

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 2262  Solved: 1129
[Submit][Status][Discuss]

Description

给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。

Input

输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。

Output

输出文件一行包含两个整数,分别表示问题1和问题2的答案。

Sample Input

5 8 2
1 2 5 8
2 5 9 9
5 1 6 2
5 1 1 8
1 2 8 7
2 5 4 9
1 2 1 1
1 4 2 1

Sample Output

13 19
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10

HINT

Source

Day1

[Submit][Status][Discuss]

时间: 2024-12-28 02:51:43

bzoj1834:最大流+最小费用最大流的相关文章

二分图/网络流/最小割/最大流/最小费用最大流等等 模板

二分图匹配: 1.匈牙利算法  O(n * m)  n为二分图左侧点数  m为二分图右侧点数 #include<bits/stdc++.h> using namespace std; const int N=1e7; struct node{ int from,to,nxt; }e[N]; int head[N],cnt; int n; int v[N],ans,A,B,d[N]; void add(int from,int to){ e[++cnt].nxt=head[from]; e[cn

POJ - 2195 Going Home(最小费用最大流)

1.N*M的矩阵中,有k个人和k个房子,每个人分别进入一个房子中,求所有人移动的最小距离. 2.人看成源点,房子看成汇点,求最小费用最大流. 建图-- 人指向房子,容量为1,费用为人到房子的曼哈顿距离. 建立超级源点和超级汇点:超级源点指向人,容量为1,费用为0:超级汇点指向房子,容量为1,费用为0. 求超级源点到超级汇点的最小费用最大流即可. ps:容量为什么都设为1?---有待研究.. 3. 1.Bellman-Ford: #include<iostream> #include<st

【BZOJ3876】【Ahoi2014】支线剧情 有下界的最小费用最大流

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43025375"); } [BZOJ2324]营救皮卡丘 这道题也是一道有下界的最小费用最大流. 我的题解地址:http://blog.csdn.net/vmurder/article/details/41378979 这道题其实就是模板题. 我的处理

POJ 3686.The Windy&#39;s 最小费用最大流

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5477   Accepted: 2285 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The ma

P3381 【模板】最小费用最大流

P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含四个正整数ui.vi.wi.fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi. 输出格式: 一行,包含两个整数,依次为最大流量和在最大流量情况下的

C++之路进阶——最小费用最大流(支线剧情)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  hyxzc Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 542  Solved: 332[Submit

hdu 4494 Teamwork 最小费用最大流

Teamwork Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4494 Description Some locations in city A has been destroyed in the fierce battle. So the government decides to send some workers to repair these location

hdu 1853 Cyclic Tour 最小费用最大流

题意:一个有向图,现在问将图中的每一个点都划分到一个环中的最少代价(边权和). 思路:拆点,建二分图,跑最小费用最大流即可.若最大流为n,则说明是最大匹配为n,所有点都参与,每个点的入度和出度又是1,所以就是环. /********************************************************* file name: hdu1853.cpp author : kereo create time: 2015年02月16日 星期一 17时38分51秒 *******

最小费用最大流

Farm Tour http://poj.org/problem?id=2135 建图再说吧 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<map> 6 #include<stack> 7 #include<queue> 8 #include<vector> 9 #include&l