【BZOJ】【1834】【ZJOI2010】Network 网络扩容

网络流/费用流



  这题……我一开始sb了。

  第一问简单的最大流……

  第二问是要建费用流的图的……但是是在第一问的最大流跑完以后的残量网络上建,而不是重建……

  我们令残量网络上原有的弧的费用全部为0(因为如果还能走就不需要扩容),而新加的弧容量为INF,费用为给定的w[i]。

  然后跑费用流就好了……这样建的话如果是不用扩容的边它就会自己走费用为0的弧。

RE/TLE:费用流扩展时的队列/边集数组的大小 M 开小了,队列长度从N改成M,M大小从20000改成50000后AC

  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 }

时间: 2024-12-28 13:28:56

【BZOJ】【1834】【ZJOI2010】Network 网络扩容的相关文章

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,表示一

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

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 Inpu

[BZOJ 1834][ZJOI2010]network 网络扩容(费用流)

Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Solution 先求出最大流maxflow 求最小扩容费用的话,对于每一条边,建一条容量为c费用为0的边,再建一条容量为INF费用为w的边 跑费用流求流入maxflow+k的费用 #include<iostream> #include<cstdio> #include

BZOJ 1834 ZJOI2010 network 网络扩容 Dinic+EK费用流

题目大意:给定一个n个点m条边的无向图,每条边有一个扩容费用c,代表每扩容1流量的花费,求最大流及将最大流扩大k的最小费用 第一问直接跑最大流 第二问将每条边的起始点向终点连接一条流量为正无穷.费用为c的边 然后将n向汇点连一条流量为ans+k 费用为0的边 跑最小费用最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 5010 #

【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)

我又思考人生了T_T,nd的数组开小了,一直wa,调了一个小时才发现啊!!!!!我一直以为我的isap错了T_T,可是完全没错啊!!!! 这题其实第一个问很简单,跑一次最大流即可.第二个问就是在跑完最大流的残量网络上每条边都扩充容量为oo,费用为边的费用,然后设个超级源连一条容量为k的边到点1,再跑一次费用流即可. 理由很简单,自己想,我就不说了. #include <cstdio> #include <cstring> #include <cmath> #includ

1834 [ZJOI2010]network 网络扩容

题解:先在原网络上跑最大流,然后加上带费用的边跑费用流 高一的时候做这道题怎么想不到? 注意:maxn代表的不一定是同一个变量的范围 #include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int inf=1000000000; const int maxn=5009; int

BZOJ 1834 ZJOI2010 network 网络扩展 Dinic+EK费用流

标题效果:给定一个n积分m无向图边,每一方有一个扩展的成本c.代表扩张1费用的交通,寻求最大流量和扩大的最大流量k最小成本 第一问直接运行的最大流量 第二个问题将是连接到一个流的末端每个边缘的起点是正无穷大.费用c缘 然后,n汇点被连接到流动ans+k 费用为0的边 跑最小费用最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 5

bzoj1834: [ZJOI2010]network 网络扩容

努力看了很久样例一直过不了...然后各种输出中间过程啊巴拉巴拉弄了1h,没办法了...然后突然想到啊原来的边可以用啊为什么不用...于是A了...感人肺腑 #include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n

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

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 Inpu

【bzoj1834】[ZJOI2010]network 网络扩容 最大流+最小费用流

题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边. 输出 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 样例输入 5 8 2 1 2 5 8 2 5 9