H - Transportation(费用流)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H - Transportation(费用流)相关的知识,希望对你有一定的参考价值。

H - Transportation(费用流)

拆边思想。

c o s t = k × f l o w 2 cost=k\\times flow^2 cost=k×flow2

因为 f l o w ≤ 5 flow \\le 5 flow5

考虑拆边,即思考如何用多条边表示: k , 4 k , 9 k , 16 k , 25 k k,4k,9k,16k,25k k,4k,9k,16k,25k

可以用前缀和思想,做个差分:5条权为 k , 3 k , 5 k , 7 k , 9 k k,3k,5k,7k,9k k,3k,5k,7k,9k,容量为1的边。

// Problem: H - Transportation
// Contest: Virtual Judge - 2010icpc [Cloned]
// URL: https://vjudge.net/contest/467412#problem/H
// Memory Limit: 32 MB
// Time Limit: 1000 ms
// Date: 2021-11-07 18:07:30
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=5e3+5,M=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = {402653189,805306457,1610612741,998244353};
#define mst(a,b) memset(a,b,sizeof a)
#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]); 
}
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 
	mc=mf=0;
	for(int i=0;i<=n;i++) pre[i].i=pre[i].u=0;
	while(spfa()){
		int u=ed,x=flow[ed];
		mf+=x;
		mc+=1LL*x*x*dis[u];
		while(u!=st){
			e[pre[u].i].f-=x;
			e[pre[u].i^1].f+=x;
			u=pre[u].u;
		}
	}
}
int main(){
	int k;
	while(~scanf("%d%d%d",&n,&m,&k)){
	st=0,ed=n;cnt=1;mst(h,0);
	add(0,1,k,0);
	rep(i,1,m){
		int u,v,f,w;
		scanf("%d%d%d%d",&u,&v,&w,&f);
		for(int i=0;i<f;i++)
			add(u,v,1,w*(2*i+1));
	}
	MCMF();
	//printf("mc=%lld mf=%lld\\n",mc,mf);
	if(mf!=k) puts("-1");
	else printf("%lld\\n",mc);
	}
	return 0;
}

以上是关于H - Transportation(费用流)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

最小费用流模板

越流越贵(最小费用最大流)

越流越贵(最小费用最大流)

hdu 3667 /2010哈尔滨赛区H题 费用与流量为非线性关系/费用流

hdu 4940 Destroy Transportation system (无源汇上下界可行流)