P4016 负载平衡问题(MCMF)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4016 负载平衡问题(MCMF)相关的知识,希望对你有一定的参考价值。
P4016 负载平衡问题(MCMF)
先求出平均值,然后比 a v e ave ave大的 连S, 否则连T,权就是差值的绝对值,费用是0.
然后相邻点连inf的权,费用为1。因为源点-S 流量 和 汇点-T 流量和 是想等的,所以最小费用就是答案。
// Problem: P4016 负载平衡问题
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4016
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2022-05-31 21:15:05
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=205,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
int cnt=1,h[N],flow[N],dis[N],vis[N],n,m,st,ed;
ll mc,mf;
int id(int x,int y)
return (x-1)*n+y;
queue<int>q;
struct edge
int to,nt,f,w;//f:flow ,w:cost
e[M];
struct Pre
int i,u;
pre[N];//记录前驱结点和边的信息,便于更新残余网络,建立反边.(反悔和贪心的思想)
void add(int u,int v,int f,int w)
e[++cnt]=v,h[u],f,w,h[u]=cnt;
e[++cnt]=u,h[v],0,-w,h[v]=cnt;
bool spfa()// 跑spfa
mst(dis,0x3f),mst(flow,0x3f),mst(vis,0); //初始化.
q.push(st),vis[st]=1,dis[st]=0,pre[ed].u=-1;//预处理
while(!q.empty())
int u=q.front();q.pop();vis[u]=0;
for(int i=h[u];i;i=e[i].nt)
int v=e[i].to,f=e[i].f,w=e[i].w;
if(f>0&&dis[v]>dis[u]+w)
dis[v]=dis[u]+w;
pre[v].u=u,pre[v].i=i;
flow[v]=min(flow[u],f);
if(!vis[v]) vis[v]=1,q.push(v);
return pre[ed].u!=-1;
void MCMF() //MIncost Maxflow
while(spfa())
int u=ed,x=flow[ed];
mf+=x;
mc+=x*dis[u];
while(u!=st)
e[pre[u].i].f-=x;
e[pre[u].i^1].f+=x;
u=pre[u].u;
int a[N];
int sum;
int main()
scanf("%d",&n);
st=n+1,ed=n+2;
rep(i,1,n)
scanf("%d",&a[i]);
sum+=a[i];
sum/=n;
rep(i,1,n) a[i]-=sum;
rep(i,1,n)
if(a[i]>0)
add(st,i,a[i],0);
else add(i,ed,-a[i],0);
rep(i,1,n)
if(i>1) add(i,i-1,inf,1);
if(i<n) add(i,i+1,inf,1);
add(1,n,inf,1);
add(n,1,inf,1);
MCMF();
printf("%lld\\n",mc);
return 0;
开发者涨薪指南
48位大咖的思考法则、工作方式、逻辑体系
以上是关于P4016 负载平衡问题(MCMF)的主要内容,如果未能解决你的问题,请参考以下文章