评论

收藏

[C++] 【BZOJ】【1834】【ZJOI2010】Network 网络扩容

编程语言 编程语言 发布于:2021-08-04 14:23 | 阅读数:410 | 评论:0

网络流/费用流这题……我一开始sb了。
第一问简单的最大流……
第二问是要建费用流的图的……但是是在第一问的最大流跑完以后的残量网络上建,而不是重建……
我们令残量网络上原有的弧的费用全部为0(因为如果还能走就不需要扩容),而新加的弧容量为INF,费用为给定的w
然后跑费用流就好了……这样建的话如果是不用扩容的边它就会自己走费用为0的弧。
RE/TLE:费用流扩展时的队列/边集数组的大小 M 开小了,队列长度从N改成M,M大小从20000改成50000后AC
DSC0000.gif DSC0001.gif
1 /**************************************************************
  2   Problem: 1834
  3   User: Tunix
  4   Language: C++
  5   Result: Accepted
  6   Time:36 ms
  7   Memory:3824 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 1834
 11 #include<vector>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<iostream>
 16 #include<algorithm>
 17 #define rep(i,n) for(int i=0;i<n;++i)
 18 #define F(i,j,n) for(int i=j;i<=n;++i)
 19 #define D(i,j,n) for(int i=j;i>=n;--i)
 20 #define pb push_back
 21 using namespace std;
 22 inline int getint(){
 23   int v=0,sign=1; char ch=getchar();
 24   while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
 25   while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
 26   return v*sign;
 27 }
 28 const int N=1002,M=50000,INF=~0u>>2;
 29 typedef long long LL;
 30 /******************tamplate*********************/
 31 int n,m,k,ans;
 32 struct edge{int from,to,v,c,w;};
 33 struct Net{
 34   edge E[M],G[M];
 35   int head[N],next[M],cnt;
 36   void ins(int x,int y,int v,int c){
 37     E[++cnt]=(edge){x,y,v,0,c};
 38     next[cnt]=head[x]; head[x]=cnt;
 39   }
 40   void add(int x,int y,int v,int c){
 41     ins(x,y,v,c); ins(y,x,0,-c);
 42   }
 43   void Ins(int x,int y,int v,int c){
 44     E[++cnt]=(edge){x,y,v,c,0};
 45     next[cnt]=head[x]; head[x]=cnt;
 46   }
 47   void Add(int x,int y,int v,int c){
 48     Ins(x,y,v,c); Ins(y,x,0,-c);
 49   }
 50   int s,t,d[N],Q[M];
 51   bool mklevel(){
 52     F(i,1,n) d[i]=-1;
 53     d[s]=0;
 54     int l=0,r=-1;
 55     Q[++r]=s;
 56     while(l<=r){
 57       int x=Q[l++];
 58       for(int i=head[x];i;i=next[i])
 59         if (d[E[i].to]==-1 && E[i].v){
 60           d[E[i].to]=d[x]+1;
 61           Q[++r]=E[i].to;
 62         }
 63     }
 64     return d[t]!=-1;
 65   }
 66   int dfs(int x,int a){
 67     if (x==t) return a;
 68     int flow=0;
 69     for(int i=head[x];i && flow<a;i=next[i])
 70       if (E[i].v && d[E[i].to]==d[x]+1){
 71         int f=dfs(E[i].to,min(a-flow,E[i].v));
 72         E[i].v-=f;
 73         E[i^1].v+=f;
 74         flow+=f;
 75       }
 76     if (!flow) d[x]=-1;
 77     return flow;
 78   }
 79   void Dinic(){
 80     while(mklevel()) ans+=dfs(s,INF);
 81   }
 82   int from[M];
 83   bool inq[N];
 84   bool spfa(){
 85     int l=0,r=-1;
 86     F(i,0,n) d[i]=INF;
 87     d[s]=0; Q[++r]=s; inq[s]=1;
 88     while(l<=r){
 89       int x=Q[l++];
 90       inq[x]=0;
 91       for(int i=head[x];i;i=next[i])
 92         if (E[i].v>0 && d[x]+E[i].c<d[E[i].to]){
 93           d[E[i].to]=d[x]+E[i].c;
 94           from[E[i].to]=i;
 95           if (!inq[E[i].to]){
 96             Q[++r]=E[i].to;
 97             inq[E[i].to]=1;
 98           }
 99         }
100     }
101     return d[n]!=INF;
102   }
103   void mcf(){
104     int x=INF;
105     for(int i=from[t];i;i=from[E[i].from])
106       x=min(x,E[i].v);
107     for(int i=from[t];i;i=from[E[i].from]){
108       E[i].v-=x;
109       E[i^1].v+=x;
110       ans+=x*E[i].c;
111     }
112   }
113   void build(){
114     int t=cnt;
115     for(int i=2;i<=t;i+=2)
116       Add(E[i].from,E[i].to,INF,E[i].w);
117   }
118   void init(){
119     n=getint(); m=getint(); k=getint();
120     int x,y,z,w;
121     cnt=1;
122     s=1; t=n;
123     F(i,1,m){
124       x=getint(); y=getint(); z=getint(); w=getint();
125       add(x,y,z,w);
126     }
127     Dinic(); build();
128     printf("%d ",ans);
129     ans=0; s=0;
130     ins(s,1,k,0);
131     while(spfa()) mcf();
132     printf("%d\n",ans);
133   }
134 }G1;
135  
136 int main(){
137 #ifndef ONLINE_JUDGE
138   freopen("1834.in","r",stdin);
139   freopen("1834.out","w",stdout);
140 #endif
141   G1.init();
142   return 0;
143 }
View Code

1834: [ZJOI2010]network 网络扩容
Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 1976  Solved: 986
[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]



关注下面的标签,发现更多相似文章