您的位置:首页 > 其它

BZOJ 1391 [Ceoi2008]order

2017-07-08 11:03 281 查看

1391: [Ceoi2008]order

Description

有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。 现在给出这些参数,求最大利润

Input

第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N块数据,每块数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,20000])

Output

最大利润

Sample Input

2 3

100 2

1 30

2 20

100 2

1 40

3 80

50

80

110

Sample Output

50

HINT

/**************************************************************
Problem: 1391
User: Doggu
Language: C++
Result: Accepted
Time:4252 ms
Memory:47844 kb
****************************************************************/

#include <cstdio>
#include <cstring>
#include <algorithm>
template<class T>inline void readin(T &res) {
static char ch;T flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;
res=ch-48;while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-48;res*=flag;
}

const int N = 10000;
const int M = 3000000;
struct Edge {int v,upre,cap,flow;}g[M];
int head
, ne=-1;
inline void adde(int u,int v,int cap) {
g[++ne]=(Edge){v,head[u],cap,0};head[u]=ne;
g[++ne]=(Edge){u,head[v],0,0};head[v]=ne;
}

#include <queue>
std::queue<int> q;
int n, m, s, t, sum, d
, cur
;
bool BFS() {
while(!q.empty()) q.pop();
memset(d,0,sizeof(d));
q.push(s);d[s]=1;
while(!q.empty()) {
int u=q.front();q.pop();
for( int i = head[u]; i != -1; i = g[i].upre ) {
int v=g[i].v;
if(!d[v]&&g[i].cap>g[i].flow) q.push(v), d[v]=d[u]+1;
}
}
return d[t];
}
int DFS(int u,int a) {
if(u==t||a==0) return a;
int flow=0, f;
for( int &i = cur[u]; i != -1; i = g[i].upre ) {
int v=g[i].v;
if(d[v]==d[u]+1&&(f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {
flow+=f;a-=f;
g[i].flow+=f;g[i^1].flow-=f;
if(a==0) break;
}
}
if(flow==0) d[u]=0;
return flow;
}
void maxflow() {
int flow=0;
while(BFS()) {
memcpy(cur,head,sizeof(head));
flow+=DFS(s,0x3f3f3f3f);
}
printf("%d\n",sum-flow);
}

int main() {
memset(head,-1,sizeof(head));
readin(n);readin(m);s=0;t=n+m+1;
for( int i = 1, w, a, b, c; i <= n; i++ ) {
readin(w);readin(b);
adde(s,i,w);sum+=w;
for( int j = 1; j <= b; j++ ) {
readin(a);readin(c);
adde(i,n+a,c);
}
}
for( int i = 1,c; i <= m; i++ ) {
readin(c);
adde(n+i,t,c);
}
maxflow();
return 0;
}


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