• bzoj1070


    题意:

    给你n个要修的车,m个人

    问你修完他们的总时间/n等于几

    题解:

    最小费用最大流

    把每个工人拆成N个点。记为A[i,j]表示第i个工人修倒数第j辆车。

    每个车跟所有N*M个工人拆出的点连边。流量为1,费用为time[i,j]*k。

    源和每辆车连边,N*M个点和汇连边,流量都为1,费用同为0。

    最小费用最大流即可

    代码:

    #include<bits/stdc++.h>
    #define inf 0x7fffffff
    #define T 601
    using namespace std;
    int n,m,cnt=1,ans,t[61][10];
    int d[605],q[605],from[605],head[605];
    bool mark[605];
    struct edge{int from,to,next,c,v;}e[100001];
    void ins(int u,int v,int w,int c)
    {
        cnt++;
        e[cnt].from=u;e[cnt].to=v;
        e[cnt].next=head[u];head[u]=cnt;
        e[cnt].c=c;e[cnt].v=w;
    }
    void jb(int u,int v,int w,int c){ins(u,v,w,c);ins(v,u,0,-c);}
    bool spfa()
    {
        memset(mark,0,sizeof(mark));
        for (int i=0;i<=T;i++)d[i]=inf;
        int t=0,w=1;
        d[T]=0;mark[T]=1;q[0]=T;
        while (t!=w)
         {
            int now=q[t];t++;
            if(t==T)t=0;
            for (int i=head[now];i;i=e[i].next)
             if (e[i^1].v&&d[e[i].to]>d[now]-e[i].c)
              {
                d[e[i].to]=d[now]-e[i].c;
                if (!mark[e[i].to])
                 {
                     mark[e[i].to]=1;
                    q[w++]=e[i].to;
                    if(w==T)w=0;
                 } 
              }
            mark[now]=0;    
         }
        if (d[0]==inf)return 0;
        return 1;
    }
    int dfs(int x,int f)
    {
        if(x==T){mark[T]=1;return f;}
        int used=0,w;
        mark[x]=1;
        for (int i=head[x];i;i=e[i].next)
         if (!mark[e[i].to]&&e[i].v&&d[x]-e[i].c==d[e[i].to])
          {
            w=f-used;
            w=dfs(e[i].to,min(e[i].v,w));
            ans+=w*e[i].c;
            e[i].v-=w;e[i^1].v+=w;
            used+=w;
            if (used==f)return f;
          }
        return used;
    }
    void zkw()
    {
        while(spfa())
        {
            mark[T]=1;
            while(mark[T])
            {
                memset(mark,0,sizeof(mark));
                dfs(0,inf);
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
         for (int j=1;j<=n;j++)scanf("%d",&t[i][j]);
        for (int i=1;i<=n*m;i++)jb(0,i,1,0);
        for (int i=n*m+1;i<=n*m+m;i++)jb(i,T,1,0);
        for (int i=1;i<=n;i++)
         for (int j=1;j<=m;j++)
          for (int k=1;k<=m;k++)jb((i-1)*m+j,n*m+k,1,t[k][i]*j);
        zkw();
        printf("%.2lf",(double)ans/m);
        return 0;
    }
  • 相关阅读:
    requirejs实现对动态combo的支持
    遇见Javascript类型数组(Typed Array)
    【转发】2012年HTML5的14个大胆预言
    跟我学canvas(三,应用图像)
    贡献一个连jquery都觉的大的时候可以用的 js库
    websocket终成标准
    Django中的form不足之处
    Eclipse+Pydev 开发Django中的Debug模式
    Javascript中指定周末日期的计算
    Python中递归的最大次数
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8447949.html
Copyright © 2020-2023  润新知