[CEOI2008]order

Description

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

Solution

相对于最大权闭合子图,多了一个租用操作
实际上把中间的\(inf\)边改成租用的费用就可以了
这样要么割在\(S\)的出边,要么割在中间,要么割在\(T\)的入边了
分别对应舍弃这种物品的利润,租用和购买了

#include<bits/stdc++.h>
using namespace std;
const int N=2505,M=3000005,inf=2e8;
int n,m,T=N-1,S=0,head[N],nxt[M],to[M],dis[M],num=1;
inline void link(int x,int y,int z){
    nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;
    nxt[++num]=head[y];to[num]=x;head[y]=num;dis[num]=0;
}
int dep[N];
inline bool bfs(){
    memset(dep,0,sizeof(dep));
    queue<int>q;
    q.push(S);dep[S]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=nxt[i]){
            int u=to[i];
            if(dis[i]<=0 || dep[u])continue;
            dep[u]=dep[x]+1;q.push(u);
        }
    }
    return dep[T];
}
inline int dfs(int x,int flow){
    if(x==T || !flow)return flow;
    int u,tot=0,t;
    for(int i=head[x];i;i=nxt[i]){
        u=to[i];
        if(dep[u]!=dep[x]+1 || dis[i]<=0)continue;
        t=dfs(u,min(flow,dis[i]));
        dis[i]-=t;dis[i^1]+=t;
        flow-=t;tot+=t;
        if(!flow)break;
    }
    if(!tot)dep[x]=-1;
    return tot;
}
inline int Dinic(){
    int t,tot=0;
    while(bfs()){
        t=dfs(S,inf);
        while(t)tot+=t,t=dfs(S,inf);
    }
    return tot;
}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  scanf("%d%d",&n,&m);
  int x,y,cnt,tot=0;
  for(int i=1;i<=n;i++){
      scanf("%d%d",&x,&cnt);
      link(S,i,x);tot+=x;
      for(int j=1;j<=cnt;j++){
          scanf("%d%d",&x,&y);
          link(i,n+x,y);
      }
  }
  for(int i=1;i<=m;i++)scanf("%d",&x),link(i+n,T,x);
  printf("%d\n",tot-Dinic());
  return 0;
}

原文地址:https://www.cnblogs.com/Yuzao/p/8447439.html

时间: 2024-10-29 00:06:18

[CEOI2008]order的相关文章

BZOJ 1391: [Ceoi2008]order [最小割]

1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Status][Discuss] Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 Input 第一行给出 N,M(1<=N<=1200,1<=M<=12

BZOJ1391: [Ceoi2008]order

1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 534  Solved: 170[Submit][Status] Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 Input 第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N块

[Luogu4177][CEOI2008]order

luogu sol 这题有点像网络流24题里面的太空飞行计划啊. 最大收益=总收益-最小损失. 先令\(ans=\sum\)任务收益. 源点向每个任务连容量为收益的边. 每个机器向汇点连容量为购买费用的边. 每个任务向对应的机器连容量为租赁费用的边. 最小割即可. code 在\(bfs\)里面用了一个玄学卡常技巧.并没有什么用 #include<cstdio> #include<algorithm> #include<cstring> #include<queu

最小割 --- [CEOI2008]order

[CEOI2008]order 题目描述: 有N个任务,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 输入格式: 第一行给出 N, M (1 <= N <= 1200, 1 <= M <= 1200) 下面将有N个任务的数据. 每组数据第一行给出完成这个任务能赚到的钱([1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(

P4177 [CEOI2008]order

P4177 [CEOI2008]order 题目描述 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 输入输出格式 输入格式: 第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N组数据. 每组数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(

BZOJ 1391: [Ceoi2008]order

Description 有一些任务,需要用到一些机器,可以买可以租,问最大获利. Solution 网络流. 最大权闭合子图模型. 建图很简单就是S->机器,机器->任务,任务->T. 如果没有租用的话,中间的是INF,不会割掉,加上租用就把容量变成租用的价格即可. 这样求出来的割就是最小损失了,用总数减去即可. Code /************************************************************** Problem: 1391 User:

1391: [Ceoi2008]order

有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 Input 第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N块数据,每块数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,

【BZOJ-1391】order 最小割 + 最大全闭合图

1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1334  Solved: 405[Submit][Status][Discuss] Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成.现在给出这些参数,求最大利润 Input 第一行给出 N,M(1<=N<=1200,1<=M<=120

一些简单的网络流模型

一.最大权闭合图 对于一个图(V, E)由点集V和一些有向边集E组成,每个点有一定权值,对于一个合法子集,若有一条有向边(u,v)并且u在子集中,则v也必须在子集中,求子集中所有元素权值和最大的子集 分析:考虑每个点有两种状况,选和不选,所以考虑最小割,但是要求最大费用: 先假设取了所有正权点,从原点向所有正权点连边,从所有负权点向汇点连边,容量为权值的绝对值, 对于一个割[S,T](S内的点表示选择了的点), 正权点在S内,表示选了这个点,与S相连的边没有被割,若在T内,表示这个点被割则被割,