【刷题】LOJ 6011 「网络流 24 题」运输问题
題目描述
W 公司有 \(m\) 個倉庫和 \(n\) 個零售商店。第 \(i\) 個倉庫有 \(a_i\) 個單位的貨物;第 \(j\) 個零售商店需要 \(b_j\) 個單位的貨物。貨物供需平衡,即 \(\sum\limits_{i = 1} ^ m a_i = \sum\limits_{j = 1} ^ n b_j\) ?。從第 \(i\) 個倉庫運(yùn)送每單位貨物到第 \(j\) 個零售商店的費(fèi)用為 \(c_{ij}\) 。試設(shè)計一個將倉庫中所有貨物運(yùn)送到零售商店的運(yùn)輸方案,使總運(yùn)輸費(fèi)用最少。
輸入格式
第 \(1\) 行有 \(2\) 個正整數(shù) \(m\) 和 \(n\) ,分別表示倉庫數(shù)和零售商店數(shù)。接下來的一行中有 \(m\) 個正整數(shù) \(a_i\) ,表示第 \(i\) 個倉庫有 \(a_i\) 個單位的貨物。再接下來的一行中有 \(n\) 個正整數(shù) \(b_j\)??,表示第 \(j\) 個零售商店需要 \(b_j\) 個單位的貨物。接下來的 \(m\) 行,每行有 \(n\) 個整數(shù),表示從第 \(i\) 個倉庫運(yùn)送每單位貨物到第 \(j\) 個零售商店的費(fèi)用 \(c_{ij}\) 。
輸出格式
兩行分別輸出最小運(yùn)輸費(fèi)用和最大運(yùn)輸費(fèi)用。
樣例
樣例輸入
2 3 220 280 170 120 210 77 39 105 150 186 122樣例輸出
48500 69140數(shù)據(jù)范圍與提示
\(1 \leq n, m \leq 100\)
題解
費(fèi)用流模板,大水題一道
源點(diǎn)向倉庫連容量為存貨,費(fèi)用為 \(0\) 的邊
商店向匯點(diǎn)連容量為需要,費(fèi)用為 \(0\) 的邊
倉庫到商店連上對應(yīng)的邊即可
最大費(fèi)用和最小費(fèi)用本質(zhì)相同,將邊的費(fèi)用變成相反數(shù)就可以了
#include<bits/stdc++.h> #define ui unsigned int #define ll long long #define db double #define ld long double #define ull unsigned long long const int MAXN=200+10,MAXM=MAXN*MAXN+10,inf=0x3f3f3f3f; int n,m,a[MAXN],b[MAXN],G[MAXN][MAXN],e,beg[MAXN],s,t,cur[MAXN],vis[MAXN],level[MAXN],to[MAXM<<1],nex[MAXM<<1],was[MAXM<<1],cap[MAXM<<1],clk,p[MAXN]; ll answas; std::queue<int> q; template<typename T> inline void read(T &x) {T data=0,w=1;char ch=0;while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();if(ch=='-')w=-1,ch=getchar();while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();x=data*w; } template<typename T> inline void write(T x,char ch='\0') {if(x<0)putchar('-'),x=-x;if(x>9)write(x/10);putchar(x%10+'0');if(ch!='\0')putchar(ch); } template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);} template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void insert(int x,int y,int z,int k) {to[++e]=y;nex[e]=beg[x];beg[x]=e;cap[e]=z;was[e]=k;to[++e]=x;nex[e]=beg[y];beg[y]=e;cap[e]=0;was[e]=-k; } inline void build(int opt) {e=1;memset(beg,0,sizeof(beg));answas=0;for(register int i=1;i<=n;++i)insert(s,i,a[i],0);for(register int i=1;i<=m;++i)insert(i+n,t,b[i],0);for(register int i=1;i<=n;++i)for(register int j=1;j<=m;++j)insert(i,j+n,inf,opt*G[i][j]); } inline bool bfs() {memset(level,inf,sizeof(level));level[s]=0;p[s]=1;q.push(s);while(!q.empty()){int x=q.front();q.pop();p[x]=0;for(register int i=beg[x];i;i=nex[i])if(cap[i]&&level[to[i]]>level[x]+was[i]){level[to[i]]=level[x]+was[i];if(!p[to[i]])p[to[i]]=1,q.push(to[i]);}}return level[t]!=inf; } inline int dfs(int x,int maxflow) {if(x==t||!maxflow)return maxflow;vis[x]=clk;int res=0;for(register int &i=cur[x];i;i=nex[i])if((vis[to[i]]^vis[x])&&cap[i]&&level[to[i]]==level[x]+was[i]){int f=dfs(to[i],min(maxflow,cap[i]));cap[i]-=f;cap[i^1]+=f;res+=f;answas+=1ll*f*was[i];maxflow-=f;if(!maxflow)break;}vis[x]=0;return res; } inline int MCMF() {int res=0;while(bfs())clk++,memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf);return res; } int main() {read(n);read(m);s=n+m+1,t=s+1;for(register int i=1;i<=n;++i)read(a[i]);for(register int i=1;i<=m;++i)read(b[i]);for(register int i=1;i<=n;++i)for(register int j=1;j<=m;++j)read(G[i][j]);build(1);MCMF();write(answas,'\n');build(-1);MCMF();write(-answas,'\n');return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/hongyj/p/9433425.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的【刷题】LOJ 6011 「网络流 24 题」运输问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [!] Attempt to read
- 下一篇: 使用python简单连接并操作数据库