BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)

不知道为什么这么慢....

费用流,拆点....

--------------------------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#include<queue>

#define rep( i, n ) for( int i = 0; i < n; ++i )

#define clr( x, c ) memset( x, c, sizeof( x ) )

#define Rep( i, n ) for( int i = 1; i <= n; ++i )

using namespace std;

const int maxn = 2000 + 5;

struct edge {

int to, cap, cost;

edge *next, *rev;

};

edge EDGE[ maxn << 3 ];

edge* pt;

edge* head[ maxn ];

void init() {

pt = EDGE;

clr( head, 0 );

}

inline void add( int u, int v, int d, int w ) {

pt -> to = v;

pt -> cap = d;

pt -> cost = w;

pt -> next = head[ u ];

head[ u ] = pt++;

}

inline void add_edge( int u, int v, int d, int w ) {

add( u, v, d, w );

add( v, u, 0, -w );

head[ u ] -> rev = head[ v ];

head[ v ] -> rev = head[ u ];

}

edge* p[ maxn ];

int d[ maxn ], a[ maxn ];

bool inQ[ maxn ];

const int INF = 0x3f3f3f3f;

int minCost( int S, int T ) {

int cost = 0;

for( ; ; ) {

clr( d, INF );

clr( inQ, 0 );

queue< int > Q;

d[ S ] = 0, a[ S ] = INF, Q.push( S );

while( ! Q.empty() ) {

int x = Q.front();

Q.pop();

inQ[ x ] = 0;

for( edge* e = head[ x ]; e; e = e->next )

if( d[ e -> to ] > d[ x ] + e -> cost && e -> cap > 0 ) {

int to = e -> to;

d[ to ] = d[ x ] + e -> cost;

a[ to ] = min( a[ x ], e -> cap );

p[ to ] = e;

if( ! inQ[ to ] )

Q.push( to ), inQ[ to ] = 1;

}

}

if( d[ T ] == INF ) break;

cost += d[ T ] * a[ T ];

int x = T;

while( x != S ) {

p[ x ] -> cap -= a[ T ];

p[ x ] -> rev -> cap += a[ T ];

x = p[ x ] -> rev -> to;

}

}

return cost;

}

int main() {

init();

int n, a, b, f[ 3 ];

cin >> n >> a >> b;

rep( i, 3 ) cin >> f[ i ];

int s = 0, t = n * 2 + 1;

Rep( i, n ) {

int x;

scanf( "%d", &x );

add_edge( s, i, x, 0 );

add_edge( s, i + n, INF, f[ 0 ] );

add_edge( i + n, t, x, 0 );

}

Rep( i, n - 1 )

add_edge( i, i + 1, INF, 0 );

for( int i = 1; i + a + 1 <= n; i++ )

add_edge( i, i + a + n + 1, INF, f[ 1 ]);

for( int i = 1; i + b + 1 <= n; i++ )

add_edge(i, i + b + n + 1, INF, f[ 2 ] );

cout << minCost( s, t ) << "\n";

return 0;

}

--------------------------------------------------------------------------------

1221: [HNOI2001] 软件开发

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 820  Solved: 449
[Submit][Status][Discuss]

Description

某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用。消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用);而且f>fA>fB。公司经理正在规划在这n天中,每天买多少块新毛巾、每天送多少块毛巾进行A种消毒和每天送多少块毛巾进行B种消毒。当然,公司经理希望费用最低。你的任务就是:为该软件公司计划每天买多少块毛巾、每天多少块毛巾进行A种消毒和多少毛巾进行B种消毒,使公司在这项n天的软件开发中,提供毛巾服务的总费用最低。

Input

第1行为n,a,b,f,fA,fB. 第2行为n1,n2,……,nn. (注:1≤f,fA,fB≤60,1≤n≤1000)

Output

最少费用

Sample Input

4 1 2 3 2 1
8 2 1 6

Sample Output

38

HINT

Source

最小费用最大流

时间: 2024-10-22 18:26:55

BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)的相关文章

[BZOJ 1221] [HNOI2001] 软件开发 【费用流 || 三分】

题目链接:BZOJ - 1221 题目分析 算法一:最小费用最大流 首先这是一道经典的网络流问题.每天建立两个节点,一个 i 表示使用毛巾,一个 i' 表示这天用过的毛巾. 然后 i 向 T 连 Ai (第 i 天需要的毛巾数).从 S 向 i' 连 Ai ,这样这天新增的用过的毛巾就是 Ai 了. 然后 i' 可以连向 (i+1)' ,表示留到下一天再处理,i' 还可以流向 i+p+1 和 i+q+1,表示洗了之后再次使用,这两种边是有费用的. 还有就是新购买毛巾,从 S 向 i 连,费用就是

BZOJ 1221: [HNOI2001] 软件开发

1221: [HNOI2001] 软件开发 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1459  Solved: 809[Submit][Status][Discuss] Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用.消

BZOJ 3280: 小R的烦恼 &amp; BZOJ 1221: [HNOI2001] 软件开发

3280: 小R的烦恼 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 399  Solved: 200[Submit][Status][Discuss] Description 小R最近遇上了大麻烦,他的程序设计挂科了.于是他只好找程设老师求情.善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题. 问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=NP,这个实验一共持续n天,第i天需要a[i]个研究生来给他搬砖.研究生毕竟也是人,

BZOJ 1449 球队收益(最小费用最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1449 题意: 思路:首先,我们假设后面的M场比赛两方都是输的,即初始时的lose[i]再加上i参加的场次.这样,后面对于i,每赢一场的收益增加值为: 之后win[i]++,lose[i]--.至此,我们得到建图的方法: (1)源点到每场比赛连流量1,费用0: (2)每场比赛向双方连流量1,费用0: (3)每个人到汇点连x条边(x为该人在M场比赛中出现的次数),流量1,费用为上面计算出的

BZOJ 1061 志愿者招募(最小费用最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元.新官上任三把火,为了出色地完成自己的工作,布

BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流

传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, 0) 如果x在目标状态是黑点,则连(mi(x), T, 1, 0) 设x的交换次数限制是w 如果x在两种状态中颜色相同,则连(in(x), mi(x), w / 2, 0), (mi(x), ou(x), w / 2, 0) 如果x只在初始状态为黑色,则连(in(x), mi(x), w / 2,

BZOJ1221 [HNOI2001] 软件开发 【费用流】

题目 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛巾,这种消毒毛巾使用一天后必须再做消毒处理后才能使用.消毒方式有两种,A种方式的消毒需要a天时间,B种方式的消毒需要b天(b>a),A种消毒方式的费用为每块毛巾fA, B种消毒方式的费用为每块毛巾fB,而买一块新毛巾的费用为f(新毛巾是已消毒的,当天可以使用):而且f>fA>fB.公司经理正

BZOJ 1877: [SDOI2009]晨跑( 最小费用最大流 )

裸的费用流...拆点, 流量限制为1, 最后的流量和费用即答案. ---------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int maxn = 409; const int INF = 1 << 30; struct edge { int to, cap, cost; edge *next, *r

BZOJ 1927: [Sdoi2010]星际竞速(最小费用最大流)

拆点,费用流... ----------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #define rep( i, n ) for( int i = 0; i < n; +