[BZOJ 1834] [ZJOI2010]network 网络扩容

1834: [ZJOI2010]network 网络扩容

Time Limit: 3 Sec
Memory Limit: 64 MB

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

【题解】

网络流啊TAT 每次都是数组开小啊

这道题第一问就是直接dinic最大流

第二问就是在做费用流的时候求出的解是满足最大流情况下的解。设第一问的最大流是ANS,要扩容K,有可能在加了新边后最大流大于ANS+K。这样费用可能不是最小的。因此我们可以在1号或N号点新增一条边,容量是K,费用是0。这样就限制了最大流。

  1 #include <stdio.h>
  2 #include <queue>
  3 #include <string.h>
  4 using namespace std;
  5 const int B=30010;
  6 const int INF=2139062143;
  7 int next[B], head[B], to[B], flow[B], w[B], c[B], oq[B];
  8 int pre[B], cnt=-1, bi[B], n, m, k, ans=0, d[B];
  9 bool vis[B];
 10 int u[B], v[B], _f[B], _w[B];
 11 queue <int> q;
 12 inline void add(int u,int v,int flo,int _w) {
 13     cnt++; to[cnt]=v; next[cnt]=head[u];    head[u]=cnt; flow[cnt]=flo; w[cnt]=_w;
 14 }
 15 inline int min(int a,int b) {return a<b?a:b;}
 16 inline void G(int &x) {
 17     int y=0, yy=1; char ch=getchar();
 18     while(ch<'0'||ch>'9') {
 19         if(ch=='-') yy=-1;
 20         ch=getchar();
 21     }
 22     while(ch>='0'&&ch<='9') {
 23         y=(y<<1)+(y<<3)+ch-'0';
 24         ch=getchar();
 25     }
 26     x=y*yy;
 27 }
 28 inline void qclear() {
 29     while(!q.empty()) q.pop();
 30 }
 31 inline bool getdfn() {
 32     qclear();
 33     memset(c,-1,sizeof(c));
 34     q.push(1); c[1]=1;
 35     while(!q.empty()) {
 36         int top=q.front();
 37         q.pop();
 38         for (int i=head[top];i>=0;i=next[i]) {
 39             int t=to[i];
 40             if(c[t]>=0||flow[i]==0) continue;
 41             c[t]=c[top]+1;
 42             q.push(t);
 43             if(t==n) return 1;
 44         } 
 45     }
 46     return 0;
 47 }
 48 int dinic(int x,int low) {
 49     if(x==n) return low;
 50     int flo,r=low;
 51     for (int i=head[x];i>=0;i=next[i]) {
 52         int t=to[i], fl=flow[i];
 53         if(c[t]!=c[x]+1 || fl==0) continue;
 54         flo=dinic(t,min(r,fl));
 55         r-=flo;
 56         flow[i]-=flo;
 57         flow[i^1]+=flo;
 58         if(!r) return low;
 59     }
 60     if(r==low) c[x]=-1;
 61     return low-r;
 62 }
 63 inline bool spfa() {
 64     memset(vis,0,sizeof(vis));
 65     memset(oq,0,sizeof(oq));
 66     memset(d,0X7f,sizeof(d));
 67     qclear();
 68     vis[1]=1; d[1]=0; q.push(1);
 69     while(!q.empty()) {
 70         int top=q.front(); q.pop();
 71         vis[top]=0; oq[top]++;
 72         if(oq[top]>n) return 0;
 73         for (int i=head[top];i>=0;i=next[i]) {
 74             if(flow[i]&&d[top]+w[i]<d[to[i]]) {
 75                 d[to[i]]=d[top]+w[i];
 76                 pre[to[i]]=i;
 77                 if(!vis[to[i]]) {
 78                     vis[to[i]]=1;
 79                     q.push(to[i]);
 80                 }
 81             }
 82         }
 83     }
 84     if(d[n]==INF) return 0;
 85     return 1;
 86 }
 87 inline void mincostflow() {
 88     int s=INF;
 89     for (int i=pre[n];i>=0;i=pre[to[i^1]]) {
 90         s=min(s,flow[i]);
 91         if(to[i^1]==1) break;
 92     }
 93     for (int i=pre[n];i>=0;i=pre[to[i^1]]) {
 94         flow[i]-=s;
 95         flow[i^1]+=s;
 96         ans+=s*w[i];
 97         if(to[i^1]==1) break;
 98     }
 99 }
100 int main() {
101     G(n), G(m), G(k);
102     memset(head,-1,sizeof(head));
103     for (int i=1;i<=m;++i) {
104         G(u[i]), G(v[i]), G(_f[i]), G(_w[i]);
105         add(u[i],v[i],_f[i],0);
106         add(v[i],u[i],0,0);
107     }
108     int _flowx=0;
109     while(getdfn()) _flowx += dinic(1,INF);
110     printf("%d ",_flowx);
111     for (int i=1;i<=m;++i) {
112         add(u[i],v[i],INF,_w[i]);
113         add(v[i],u[i],0,-_w[i]);
114     }
115     add(n,n+1,k,0); add(n+1,n,0,0);
116     ++n;
117     while(spfa()) mincostflow();
118     printf("%d\n",ans);
119     return 0;
120 }
View Code

 

posted @ 2015-07-09 11:36  TonyFang  阅读(334)  评论(0编辑  收藏  举报