BZOJ1834 [ZJOI2010] network 网络扩容

Posted ACMICPC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1834 [ZJOI2010] network 网络扩容相关的知识,希望对你有一定的参考价值。

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1834

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的答案。

就是想学一个费用流模版,交到BZOJ上无限TLE

下载到了数据,发现数据是“错误”的,然后才发现有的是Windows/DOS格式有的是UNIX格式……

然后调,发现程序在读入一半的时候就会崩掉,开调试把我带进了头文件,以为自己遇到了OI生涯最大的玄学

然后在来学校的车上猛然想起自己记录边的数组开小了,maxm打成maxn了……

真是“玄学”,原来是低级错误在作怪……

似乎我也荒废挺久了

技术分享

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <queue>
  6 #define rep(i,l,r) for(int i=l; i<=r; i++)
  7 #define clr(x,y) memset(x,y,sizeof(x))
  8 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
  9 using namespace std;
 10 const int INF = 0x3f3f3f3f;
 11 const int maxn = 1010;
 12 const int maxm = 5010;
 13 inline int read(){
 14     int ans = 0, f = 1;
 15     char c = getchar();
 16     for(; !isdigit(c); c = getchar())
 17     if (c == -) f = -1;
 18     for(; isdigit(c); c = getchar())
 19     ans = ans * 10 + c - 0;
 20     return ans * f;
 21 }
 22 struct Edge{
 23     Edge *pre,*rev; int to,cap,cost;
 24 }edge[maxm<<2],*last[maxn],*cur[maxn],*pre[maxn],*pt;
 25 int n,m,k,u[maxm],v[maxm],c[maxm],x,d[maxn],S,T;
 26 bool isin[maxn];
 27 queue <int> q;
 28 inline void init(){
 29     clr(last,0); pt = edge;
 30 }
 31 inline void add(int x,int y,int z,int w){
 32     pt->pre = last[x]; pt->to = y; pt->cap = z; pt->cost = w; last[x] = pt++;
 33     pt->pre = last[y]; pt->to = x; pt->cap = 0; pt->cost = -w; last[y] = pt++;
 34     last[x]->rev = last[y]; last[y]->rev = last[x];
 35 }
 36 bool bfs(){
 37     while (!q.empty()) q.pop();
 38     clr(d,-1); d[S] = 0; q.push(S);
 39     while (!q.empty()){
 40         int now = q.front(); q.pop();
 41         travel(now){
 42             if (p->cap > 0 && d[p->to] == -1){
 43                 d[p->to] = d[now] + 1;
 44                 q.push(p->to);
 45                 if (p->to == T) return 1;
 46             }
 47         }
 48     }
 49     return 0;
 50 }
 51 int dfs(int x,int flow){
 52     if (x == T || (!flow)) return flow; int w = 0;
 53     for(Edge *p = cur[x]; p && w < flow; p = p->pre){
 54         if (d[p->to] == d[x] + 1 && p->cap > 0){
 55             int delta = dfs(p->to,min(p->cap,flow-w));
 56             p->cap -= delta; p->rev->cap += delta; w += delta;
 57             if (p->cap) cur[x] = p;
 58         }
 59     }
 60     if (w < flow) d[x] = -1;
 61     return w;
 62 }
 63 int maxflow(){
 64     int ans = 0;
 65     while (bfs()){
 66         rep(i,1,n) cur[i] = last[i];
 67         ans += dfs(S,0x7fffffff);
 68     }
 69     return ans;
 70 }
 71 bool spfa(){
 72     while (!q.empty()) q.pop();
 73     clr(d,INF); clr(isin,0);
 74     d[S] = 0; isin[S] = 1; q.push(S);
 75     while (!q.empty()){
 76         int now = q.front(); q.pop(); isin[now] = 0;
 77         travel(now){
 78             if (p->cap && d[p->to] > d[now] + p->cost){
 79                 d[p->to] = d[now] + p->cost;
 80                 pre[p->to] = p;
 81                 if (!isin[p->to]){
 82                     isin[p->to] = 1; q.push(p->to);
 83                 }
 84             }
 85         }
 86     }
 87     return d[T] != INF;
 88 }
 89 int mincost(){
 90     int cost = 0; int x = INF;
 91     while (spfa()){
 92         for(Edge *p = pre[T]; p; p = pre[p->rev->to]) x = min(x,p->cap);
 93         for(Edge *p = pre[T]; p; p = pre[p->rev->to]){
 94             cost += x * p->cost; p->cap -= x; p->rev->cap += x;
 95         }
 96     }
 97     return cost;
 98 }
 99 int main(){
100     n = read(); m = read(); k = read(); init();
101     rep(i,1,m){
102         u[i] = read(); v[i] = read(); x = read(); c[i] = read();
103         add(u[i],v[i],x,0);
104     }
105     S = 1; T = n; printf("%d ",maxflow());
106     S = 0; T = n + 1;
107     rep(i,1,m) add(u[i],v[i],INF,c[i]); 
108     add(0,1,k,0); add(n,n+1,k,0);
109     printf("%d\n",mincost());
110     return 0;
111 }
View Code

 

以上是关于BZOJ1834 [ZJOI2010] network 网络扩容的主要内容,如果未能解决你的问题,请参考以下文章

bzoj:1834: [ZJOI2010]network 网络扩容

BZOJ 1834 [ZJOI2010]network 网络扩容

bzoj1834 ZJOI2010网络扩容(费用流)

[ZJOI2010][bzoj1834] 网络扩容 [费用流]

[ZJOI2010]网络扩容

[ZJOI2010]网络扩容