• [bzoj1070][SCOI2007]修车[ 网络流]


    把每个工人拆成N个点。记为A[i,j]表示第i个工人修倒数第j辆车.每个车跟所有N*M个工人拆出的点连边。流量为1,费用为$time[i,j]*k$。源和每辆车连边,N*M个点和汇连边,流量都为1,费用同为0。

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <ctime>
      7 #include <cmath>
      8 #include <queue>
      9 
     10 using namespace std;
     11 
     12 template<const int _n,const int _m>
     13 struct Edge
     14 {
     15     struct Edge_base { int to,next,w,c; }e[_m]; int    cnt,p[_n];
     16     void    clear() { cnt=1,memset(p,0,sizeof(p)); }
     17     Edge() { clear(); }
     18     void    insert(const int x,const int y,const int z,const int zz)
     19     { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; e[cnt].c=zz; p[x]=cnt; return ; }
     20     void    link(const int x,const int y,const int z,const int zz)
     21     { insert(x,y,z,zz); insert(y,x,0,-zz); }
     22     int    start(const int x) { return p[x]; }
     23     Edge_base& operator[](const int x) { return e[x]; }
     24 };
     25 
     26 int    n,m,Time[61][10],SSS,TTT,Cost;
     27 int    Dis[610],cur[610];
     28 bool    visited[610];
     29 Edge<610,71000>e;
     30 
     31 bool    Spfa(const int S)
     32 {
     33     int    i,t,temp;
     34     queue<int>    Q;
     35     memset(Dis,0x3f,sizeof(Dis));
     36     Dis[S]=0;
     37     visited[S]=true;
     38     Q.push(S);
     39     while(!Q.empty())
     40     {
     41         t=Q.front();Q.pop();visited[t]=false;
     42         for(i=e.start(t);i;i=e[i].next)
     43         {
     44             temp=e[i].to;
     45             if(e[i].w && Dis[t]+e[i].c<Dis[temp])
     46             {
     47                 Dis[temp]=Dis[t]+e[i].c;
     48                 if(!visited[temp])
     49                 {
     50                     visited[temp]=true;
     51                     Q.push(temp);
     52                 }
     53             }
     54         }
     55     }
     56     return Dis[TTT]!=0x3f3f3f3f;
     57 }
     58 
     59 int    Dfs(const int S,const int bk)
     60 {
     61     visited[S]=true;
     62     if(S==TTT)return bk;
     63     int    rest=bk;
     64     for(int &i=cur[S];i;i=e[i].next)
     65     {
     66         if(!visited[e[i].to] && Dis[S]+e[i].c==Dis[e[i].to] && e[i].w)
     67         {
     68             int    flow=Dfs(e[i].to,min(rest,e[i].w));
     69             Cost+=flow*e[i].c;
     70             e[i].w-=flow;
     71             e[i^1].w+=flow;
     72             if((rest-=flow)<=0)break;
     73         }
     74     }
     75     if(bk==rest)Dis[S]=0x3f3f3f3f;
     76     return bk-rest;
     77 }
     78 
     79 int    Zkw()
     80 {
     81     while(Spfa(SSS))
     82     {
     83         do
     84         {
     85             memset(visited,0,sizeof(visited));
     86             memcpy(cur,e.p,sizeof(cur));
     87             Dfs(SSS,0x3f3f3f3f);
     88         }while(visited[TTT]);
     89     }
     90     return Cost;
     91 }
     92 
     93 int main()
     94 {
     95     int    i,j,k;
     96 
     97     scanf("%d%d",&n,&m);
     98     for(i=1;i<=m;++i)
     99         for(j=1;j<=n;++j)
    100             scanf("%d",&Time[i][j]);
    101     SSS=n*m+m+1,TTT=SSS+1;
    102     for(i=1;i<=n*m;++i)e.link(SSS,i,1,0);
    103     for(i=n*m+1;i<SSS;++i)e.link(i,TTT,1,0);
    104     for(k=1;k<=m;++k)
    105         for(i=1;i<=n;++i)
    106             for(j=1;j<=m;++j)
    107                 e.link((i-1)*m+j,n*m+k,1,Time[k][i]*j);
    108     printf("%.2lf
    ",(double)Zkw()/m);
    109     return 0;
    110 }
  • 相关阅读:
    高并发时,使用Redis应注意的问题 及 Redis缓存帮助类
    NetCore3.1 如何添加带有JWT Token 验证的Swagger
    CSS 技巧一则 -- 不定宽溢出文本适配滚动
    ROS costmap_2d局部障碍物无法清除和机器人到点摇摆
    ROS OccupancyGrid使用说明
    ROS RVIZ显示点云地图的二维投影
    Linux 文档生成器doxygen
    高翔博士 资源索引
    SLAM中的数学基础 第四篇 李群与李代数2
    shell(8):循环
  • 原文地址:https://www.cnblogs.com/Gster/p/5090533.html
Copyright © 2020-2023  润新知