您的位置:首页 > 编程语言 > Go语言

【CF 724E】Goods transportation(最小割+DP)

2016-10-10 17:48 453 查看
【CF 724E】Goods transportation(最小割+DP)

题目大意:

n个工厂,每个工厂有生产量pi和最多销售量si。小编号工厂可以往大编号工厂运送货物,每对工厂最多传送c单位的货物。传送顺序随意。

问最终所有工厂最多销售量。

可以想到最大流。源点与每个工厂一条边,流量pi,每个工厂和汇点一条边,流量si。每个小工厂往每个大工厂有一条边,流量c。

跑完就可以得到结果了。

但是这题n 10^4,图是妥妥的建不出来。由长者们推出来的定理:最大流=最小割……

考虑将图分成两部分,集合A与集合B,A中有源点,B中有汇点,A∪B=原图。

这样割就是∑i∈Asi+∑j∈Bpj+∑i<j,i∈A,j∈Bc

画出图来比较好看。大体就是:



被叉掉的就是一个割,也就是刚才那一长串。

求最小割的dp数组的定义也很绝。

dp[i][j]表示图中存在1~i工厂,其中j个工厂与源点连通的最小割。

枚举工厂1~n,加点求min就行了。要注意的是直接n^2内存开不下,要做成滚动数组。

代码如下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <ctime>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread(ch) freopen(ch,"r",stdin)
#define fwrite(ch) freopen(ch,"w",stdout)

using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-8;
const int maxn = 11234;

LL p[maxn],s[maxn];
LL dp[2][maxn];

int main()
{
//fread("");
//fwrite("");

int n;
LL c;

scanf("%d%lld",&n,&c);

for(int i = 1; i <= n; ++i) scanf("%lld",&p[i]);
for(int i = 1; i <= n; ++i) scanf("%lld",&s[i]);

int pre = 1;
memset(dp,INF,sizeof(dp));

dp[pre][0] = 0;

for(int i = 1; i <= n; ++i)
{
pre ^= 1;

for(int j = 0; j <= i; ++j)
{
dp[pre][j] = dp[pre^1][j]+p[i]+j*c;
if(j) dp[pre][j] = min(dp[pre][j],dp[pre^1][j-1]+s[i]);
}
}

LL ans = dp[pre][0];

for(int i = 1; i <= n; ++i)
ans = min(ans,dp[pre][i]);

printf("%lld\n",ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: