【问题分析】
费用流问题。
【建模方法】
把所有仓库看做二分图中顶点Xi,所有零售商店看做二分图中顶点Yi,建立附加源S汇T。
1、从S向每个Xi连一条容量为仓库中货物数量ai,费用为0的有向边。
2、从每个Yi向T连一条容量为商店所需货物数量bi,费用为0的有向边。
3、从每个Xi向每个Yj连接一条容量为无穷大,费用为cij的有向边。
求最小费用最大流,最小费用流值就是最少运费,求最大费用最大流,最大费用流值就是最多运费。
【建模分析】
把每个仓库想象成一个中转站,由源点运来ai单位货物,运费为0,每个商店也为一个中转站,运向目标汇点bi单位货物。每个仓库和零售商店之间有一条道路,容量为无穷大,费用为单位运费cij。求从源点到汇点的费用流,就是运费。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int N = 5e3 + 7, M = 2e6 + 7, INF = 0x3f3f3f3f;
int cost[N][N];
namespace dinic{
//MCMF
const int N = 1e5 + 7, M = 2e6 + 7;
const ll INF = 0x3f3f3f3f3f;//!因为是long long 所以是五个3f
int n, S, T;
int head[N], ver[M], nex[M], tot, cur[N];
ll dist[N], edge[M], cost[M], maxflow, mincost;
bool vis[N];
inline void add(int x, int y, ll z, ll c, bool o = 1){
ver[tot] = y;
edge[tot] = z;
cost[tot] = c;
nex[tot] = head[x];
head[x] = tot ++ ;
if(o)add(y, x, 0, -c, 0);
}
inline bool