[bzoj1834]网络扩容

时间:2019-11-10
本文章向大家介绍[bzoj1834]网络扩容,主要包括[bzoj1834]网络扩容使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

第一问直接最大流即可,记这个最大流为ans
第二问可以在原图的基础上,初始边费用为0,新增费用为w流量为inf的边,新增0号点向1流一条流量为ans+k,费用为0的边,跑最小费用最大流即可
考虑这个过程中,由于费用都为正,所以一定先走费用为0的边,相当于现求最大流,所以可以直接在残余网络上加入费用为w,流量为inf的边即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1005
 4 struct ji{
 5     int nex,to,len,cost;
 6 }edge[N*20];
 7 queue<int>q;
 8 int E,n,m,k,x,y,z,w,head[N],work[N],d[N],from[N],vis[N];
 9 void add(int x,int y,int z,int w){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     edge[E].len=z;
13     edge[E].cost=w;
14     head[x]=E++;
15     if (E&1)add(y,x,0,-w);
16 }
17 bool bfs(){
18     memset(d,-1,sizeof(d));
19     q.push(1);
20     d[1]=0;
21     while (!q.empty()){
22         int k=q.front();
23         q.pop();
24         for(int i=head[k];i!=-1;i=edge[i].nex)
25             if ((edge[i].len)&&(d[edge[i].to]<0)){
26                 d[edge[i].to]=d[k]+1;
27                 q.push(edge[i].to);
28             }
29     }
30     return d[n]>=0;
31 } 
32 int dfs(int k,int s){
33     if (k==n)return s;
34     int p;
35     for(int &i=work[k];i!=-1;i=edge[i].nex)
36         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
37             p=dfs(edge[i].to,min(s,edge[i].len));
38             if (p){
39                 edge[i].len-=p;
40                 edge[i^1].len+=p;
41                 return p;
42             }
43         }
44     return 0;
45 }
46 bool spfa(){
47     memset(d,0x3f,sizeof(d));
48     memset(vis,0,sizeof(vis));
49     q.push(0);
50     d[0]=0;
51     while (!q.empty()){
52         int k=q.front();
53         q.pop();
54         vis[k]=0;
55         for(int i=head[k];i!=-1;i=edge[i].nex){
56             int v=edge[i].to;
57             if ((edge[i].len)&&(d[v]>d[k]+edge[i].cost)){
58                 d[v]=d[k]+edge[i].cost;
59                 from[v]=i;
60                 if (!vis[v]){
61                     vis[v]=1;
62                     q.push(v);
63                 }
64             }
65         }
66     }
67     return d[n]<0x3f3f3f3f;
68 }
69 int main(){
70     scanf("%d%d%d",&n,&m,&k);
71     memset(head,-1,sizeof(head));
72     for(int i=1;i<=m;i++){
73         scanf("%d%d%d%d",&x,&y,&z,&w);
74         add(x,y,z,w);
75     }
76     int ans=0;
77     while (bfs()){
78         memcpy(work,head,sizeof(head));
79         while (x=dfs(1,0x3f3f3f3f))ans+=x;
80     }
81     printf("%d ",ans);
82     for(int i=0;i<m;i++){
83         add(edge[i*2+1].to,edge[i*2].to,0x3f3f3f3f,edge[i*2].cost);
84         edge[i*2].cost=edge[i*2+1].cost=0;
85     }
86     add(0,1,k,0);
87     ans=0;
88     while (spfa()){
89         x=0x3f3f3f3f;
90         for(int i=n;i;i=edge[from[i]^1].to)x=min(x,edge[from[i]].len);
91         ans+=x*d[n];
92         for(int i=n;i;i=edge[from[i]^1].to){
93             edge[from[i]].len-=x;
94             edge[from[i]^1].len+=x;
95         }
96     }
97     printf("%d",ans);
98 } 
View Code

原文地址:https://www.cnblogs.com/PYWBKTDA/p/11830624.html