BZOJ1834: [ZJOI2010]network 网络扩容

1834: [ZJOI2010]network 网络扩容

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 3490  Solved: 1827
[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

 

 

先求最大流,然后在残余网络上建图,对于原有的每一条边建一条容量INF费用c的边,新源点S指向1容量k费用0即可

莫名其妙被Longlong传参int卡了?

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #define min(a, b) ((a) < (b) ? (a) : (b))
  9 #define max(a, b) ((a) > (b) ? (a) : (b))
 10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 11 inline void swap(int &a, int &b)
 12 {
 13     int tmp = a;a = b;b = tmp;
 14 }
 15 inline void read(int &x)
 16 {
 17     x = 0;char ch = getchar(), c = ch;
 18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 20     if(c == '-') x = -x;
 21 }
 22 
 23 const int INF = 0x3f3f3f3f;
 24 const int MAXN = 100000 + 10;
 25 const int MAXM = 500000 + 10;
 26 const int MAXK = 10 + 2;
 27 
 28 struct Edge
 29 {
 30     int u,v,nxt,w,c;
 31     Edge(int _u, int _v, int _nxt, int _w, int _c){u = _u;v = _v;nxt = _nxt;w = _w;c = _c;} 
 32     Edge(){}
 33 }edge[MAXM << 1];
 34 
 35 int cnt = 1, head[MAXN], from[MAXN];
 36 bool b[MAXN];
 37 int S, T;
 38 int d[MAXN], ans;
 39 int q[MAXN << 1];
 40 int n,m,k;
 41 
 42 inline void insert(int u, int v, int w, int c)
 43 {
 44     edge[++cnt] = Edge(u, v, head[u], w, c);
 45     head[u] = cnt;
 46     edge[++cnt] = Edge(v, u, head[v], 0, -c);
 47     head[v] = cnt;
 48 }
 49 
 50 bool spfa()
 51 {
 52     memset(d, 0x3f, sizeof(d));
 53     int he = 0, ta = 1;
 54     d[S] = 0, b[S] = 1, q[he] = S;
 55     while(he != ta)
 56     {
 57         int now = q[he ++];
 58         if(he > n) he = 0;
 59         for(int pos = head[now];pos;pos = edge[pos].nxt)
 60             if(edge[pos].w && d[edge[pos].v] > d[now] + edge[pos].c)
 61             {
 62                 d[edge[pos].v] = d[now] + edge[pos].c;
 63                 from[edge[pos].v] = pos;
 64                 if(!b[edge[pos].v])
 65                 {
 66                     b[edge[pos].v]=1;
 67                     q[ta ++] = edge[pos].v;
 68                     if(ta > n)ta = 0;
 69                 } 
 70             }
 71         b[now] = 0; 
 72     }
 73     if(d[T] == INF)return 0;
 74     return 1;
 75 }
 76 
 77 void flow()
 78 {
 79     int x = INF;
 80     for(int i = from[T];i;i = from[edge[i].u])
 81         x = min(x, edge[i].w);
 82     for(int i = from[T];i;i = from[edge[i].u])
 83     {
 84         edge[i].w -= x;
 85         edge[i^1].w += x;
 86         ans += edge[i].c * x;
 87     }
 88 }
 89 
 90 void mcmf()
 91 {
 92     while(spfa()) flow();
 93 }
 94 
 95 int h[MAXN << 1], qq[MAXN];
 96 
 97 bool bfs()
 98 {
 99     int he = 0, ta = 1;
100     memset(h, -1, sizeof(h));
101     h[S] = 0;qq[he] = S;
102     while(he < ta)
103     {
104         int now = qq[he ++];
105         for(int pos = head[now];pos;pos = edge[pos].nxt)
106         {
107             int v = edge[pos].v;
108             if(h[v] == -1 && edge[pos].w)
109             {
110                 h[v] = h[now] + 1;
111                 qq[ta ++] = v;
112             }
113         }
114     }
115     return h[T] != -1;
116 }
117 int dfs(int x, int f)
118 {
119     if(x == T) return f;
120     int w, used = 0;
121     for(int pos = head[x];pos;pos = edge[pos].nxt)
122     {
123         int v = edge[pos].v;
124         if(h[v] == h[x] + 1)
125         {
126             w = dfs(v, min(f - used, edge[pos].w));
127             edge[pos].w -= w;
128             edge[pos ^ 1].w += w;
129             used += w;
130             if(used == f) return f;
131         }
132     }
133     if(!used) h[x] = -1;
134     return used;
135 }
136 void dinic()
137 {
138     while(bfs()) ans += dfs(S, INF);
139 }
140 
141 int u[MAXM], v[MAXM], w[MAXM], c[MAXM];
142 
143 int main()
144 {
145     read(n), read(m), read(k);
146     for(register int i = 1;i <= m;++ i)
147     {
148         read(u[i]), read(v[i]), read(w[i]), read(c[i]);
149         insert(u[i], v[i], w[i], 0);
150     }
151     S = 1, T = n;
152     dinic();
153     printf("%d ", ans);
154     ans = 0;
155     for(register int i = 1;i <= m;++ i)
156         insert(u[i], v[i], INF, c[i]);
157     S = 1100;
158     insert(S, 1, k, 0);
159     mcmf();
160     printf("%d", ans);
161     return 0;
162 } 
BZOJ1834

 

posted @ 2018-01-15 23:47  嘒彼小星  阅读(166)  评论(0编辑  收藏  举报