hello everyone,大家好,我是love——putter,好久没发题解了(因为没素材了)所以,今天来发一下P3381 【模板】最小费用最大流的题解
给出一个包含 nn 个点和 mm 条边的有向图(下面称其为网络) G=(V,E)G=(V,E),该网络上所有点分别编号为 1 \sim n1∼n,所有边分别编号为 1\sim m1∼m,其中该网络的源点为 ss,汇点为 tt,网络上的每条边 (u,v)(u,v) 都有一个流量限制 w(u,v)w(u,v) 和单位流量的费用 c(u,v)c(u,v)。
你需要给每条边 (u,v)(u,v) 确定一个流量 f(u,v)f(u,v),要求:
定义网络 GG 的流量 F(G)=\sum_{(s,i)\in E}f(s,i)F(G)=∑(s,i)∈Ef(s,i),网络 GG 的费用 C(G)=\sum_{(i,j)\in E} f(i,j) \times c(i,j)C(G)=∑(i,j)∈Ef(i,j)×c(i,j)。
你需要求出该网络的最小费用最大流,即在 F(G)F(G) 最大的前提下,使 C(G)C(G) 最小。
输入第一行包含四个整数 n,m,s,tn,m,s,t,分别代表该网络的点数 nn,网络的边数 mm,源点编号 ss,汇点编号 tt。
接下来 mm 行,每行四个整数 u_i,v_i,w_i,c_iui,vi,wi,ci,分别代表第 ii 条边的起点,终点,流量限制,单位流量费用。
输出两个整数,分别为该网络的最大流 F(G)F(G),以及在 F(G)F(G) 最大的前提下,该网络的最小费用 C(G)C(G)。
输入 #1复制
4 5 4 3 4 2 30 2 4 3 20 3 2 3 20 1 2 1 30 9 1 3 40 5
输出 #1复制
50 280
对于 100\%100% 的数据,1 \leq n \leq 5\times 10^31≤n≤5×103,1 \leq m \leq 5 \times 10^41≤m≤5×104,1 \leq s,t \leq n1≤s,t≤n,u_i \neq v_iui=vi,0 \leq w_i,c_i \leq 10^30≤wi,ci≤103,且该网络的最大流和最小费用 \leq 2^{31}-1≤231−1。
输入数据随机生成。
代码,(答案仅能得54分 求大佬帮忙。)
#include
#define ll long long
using namespace std;
const int N=5e3+5;
const int M=5e4+5;
struct edge {
int v;
int r;
int c;
int next;
} es[M<<1];
int n,m,s,t,cnt=1;
int head[N];
queue
int cost[N],dis[N],pre[N];
bool vis[N];
ll maxflow,mincost;
void addedge(int u,int v,int w,int c)
{
cnt++;
es[cnt].v=v;
es[cnt].r=w;
es[cnt].c=c;
es[cnt].next=head[u];
head[u]=cnt;
}
bool SPFA()
{
memset(cost,0x7f,sizeof(cost));
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
cost[s]=0;
q.push(s);
vis[s]=true;
while (!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for (int i=head[u];i>0;i=es[i].next)
{
edge e=es[i];
if (e.r>0 && cost[u]+e.c
cost[e.v]=cost[u]+e.c;
pre[e.v]=i;
dis[e.v]=min(dis[u],e.r);
if (!vis[e.v])
{
q.push(e.v);
vis[e.v]=true;
}
}
}
}
}
void minCostMaxFlow()
{
while (SPFA())
{
int now=t;
maxflow+=dis[t];
mincost+=dis[t]*cost[t];
while (now!=s)
{
int loc=pre[now];
es[loc].r-=dis[t];
es[loc^1].r+=dis[t];
now=es[loc^1].v;
}
}
}
int main()
{
int u,v,w,c;
cin>>n>>m>>s>>t;
for (int i=1;i<=m;i++)
{
cin>>u>>v>>w>>c;
addedge(u,v,w,c);
addedge(v,u,0,-c);
}
minCostMaxFlow();
cout<
}