• CEOI2008 order


    申请了博客不发点东西总觉得不太好

    虽然这个题是CEOI的题,但是时间有点久远,现在看来是一道网络流很好的练手题。

    透过现象看本质,我们可以发现,每台机器只有租或者买两个选项,且只能二选一,这种二选一,每种选择还有不同权值的东西,我们可以大胆猜测是要求最小割,然后手动画图手玩一下就会发现果然没错。

    然后就是建图,网络流的题一般来说只要找到建图的方法,剩下的就是无脑套板子了,所以我们需要思考建图方案。而这对于本蒟蒻来说,简直困难到炸(适当装弱有益健康)。

    源点向所有工作连边,权值为收益;工作向机器连边,权值为租用费用;机器向汇点连边,权值为购买费用。

    剩下的就是最小割板子了。

    (吐槽一下当初我看的那一篇讲dinic的文章,附的板子奇慢无比。。。水题都会T,我还以为是我自带巨大常数(虽然确实我自带巨大常数)。。。)

    //made by Crazy01
    #include<map>
    #include<queue>
    #include<math.h>
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    #define inf 1<<30
    #define LL long long
    #define c233 cout<<"233"<<endl
    #define mem(s) memset(s,0,sizeof(s))
    #define M 4500000
    #define N 4050
    #define il inline
    using namespace std;
    
    int nxt[M],t[M],w[M],head[N],dis[N],que[N];
    int n,m,maxe=1,S,T,all,hd,tl;
    
    il int min(int x,int y){
      return x<y?x:y;
    }
    
    il int gi(){
      int x=0,res=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
      while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
      return x*res;
    }
    
    il void build(int a,int b,int c){
      nxt[++maxe]=head[a];t[maxe]=b;w[maxe]=c;head[a]=maxe;
      nxt[++maxe]=head[b];t[maxe]=a;w[maxe]=0;head[b]=maxe;
    }
    
    il void init(){
      n=gi();m=gi();
      S=0;T=m+n+1;
      for(int i=1;i<=n;i++){
        int a=gi(),b=gi();
        build(S,i,a);
        all+=a;
        for(int j=1;j<=b;j++){
          int x=gi(),y=gi();
          build(i,x+n,y);
        }
      }
      for(int i=1;i<=m;i++){
        int x=gi();
        build(i+n,T,x);
      }
    }
    
    il bool bfs(){
      hd=tl=0;
      for(int i=S;i<=T;i++)dis[i]=-1;
      dis[S]=0;que[hd]=S;tl++;
      while(hd<tl){
        int x=que[hd];hd++;
        if(x==T)return 1;
        for(int i=head[x];i;i=nxt[i]){
          int to=t[i],f=w[i];
          if(f>0&&dis[to]==-1){
    	    dis[to]=dis[x]+1;
    	    que[tl++]=to;
          }
        }
      }
      return 0;
    }
    
    il int dfs(int x,int flll){
      if(x==T)return flll;
      int tag=0;
      for(int i=head[x];i;i=nxt[i]){
        int to=t[i],f=w[i];
        if(dis[to]==dis[x]+1&&f>0){
          f=dfs(to,min(flll-tag,f));
          tag+=f;
          w[i]-=f;w[i^1]+=f;
          if(tag==flll)return tag;
        }
      }
      if(tag==0)dis[x]=-1;
      return tag;
    }
    
    il void dinic(){
      while(bfs())all-=dfs(S,inf);
      printf("%d
    ",all);
    }
    
    int main(){
      init();
      dinic();
      return 0;
    }

    附带相关格式样例

    输入格式:

    第一行两个整数,n 和 m,分别表示工作数和机器数.

    接下来输入分为 n 段,即对于每项工作:

    第一行为两个整数,a 和 b,分别为完成该工作的收益和工序数;

    接下来 b 行,每行两个整数,x 和 y,分别表示完成该工序需要的机器和机器的租赁费用.

    接下来一行有 m 个数, wi 表示购买每台机器的费用.

    输出格式:

    输出仅一行,即可以获得的最大收益.

    输入样例:

    5 5
    1 3
    2 3
    3 2
    5 5
    1 1
    2 2
    4 1
    5 2
    4 4
    1 4
    2 3
    3 3
    4 2
    5 5
    1 5
    2 3
    3 3
    4 1
    5 5
    1 1 1 4 4

    输出样例:

    5

     

  • 相关阅读:
    前台查询条件参数多时封装成一个bean
    struts2操作json成字符串格式错误被转义及其前台访问json对象的方法
    hibernate第一课第一个自己的helloworld
    easyui中的tree数据使用说明
    css设计课堂笔记,有关样式的
    前台取json对象中的数据
    myeclipse自动生成代码SSH2
    jquery获取子对象操作
    iframe自适应高度调整
    组织配置java项目的外部lib包
  • 原文地址:https://www.cnblogs.com/Crazy01/p/7258793.html
Copyright © 2020-2023  润新知