[BZOJ 1834] [ZJOI2010]network 网络扩容
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ 1834] [ZJOI2010]network 网络扩容
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1834: [ZJOI2010]network 網(wǎng)絡(luò)擴(kuò)容
Time Limit:?3 SecMemory Limit:?64 MBDescription
給定一張有向圖,每條邊都有一個容量C和一個擴(kuò)容費(fèi)用W。這里擴(kuò)容費(fèi)用是指將容量擴(kuò)大1所需的費(fèi)用。求: 1、 在不擴(kuò)容的情況下,1到N的最大流; 2、 將1到N的最大流增加K所需的最小擴(kuò)容費(fèi)用。Input
輸入文件的第一行包含三個整數(shù)N,M,K,表示有向圖的點(diǎn)數(shù)、邊數(shù)以及所需要增加的流量。 接下來的M行每行包含四個整數(shù)u,v,C,W,表示一條從u到v,容量為C,擴(kuò)容費(fèi)用為W的邊。Output
輸出文件一行包含兩個整數(shù),分別表示問題1和問題2的答案。Sample Input
5 8 21 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 1930%的數(shù)據(jù)中,N<=100
100%的數(shù)據(jù)中,N<=1000,M<=5000,K<=10
HINT
Source
Day1
【題解】
網(wǎng)絡(luò)流啊TAT 每次都是數(shù)組開小啊
這道題第一問就是直接dinic最大流
第二問就是在做費(fèi)用流的時候求出的解是滿足最大流情況下的解。設(shè)第一問的最大流是ANS,要擴(kuò)容K,有可能在加了新邊后最大流大于ANS+K。這樣費(fèi)用可能不是最小的。因此我們可以在1號或N號點(diǎn)新增一條邊,容量是K,費(fèi)用是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?
轉(zhuǎn)載于:https://www.cnblogs.com/TonyNeal/p/bzoj1834.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ 1834] [ZJOI2010]network 网络扩容的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世纪互联云和华为共同打造的数据中心是一个
- 下一篇: ld: -pie can only be