zoukankan      html  css  js  c++  java
  • BZOJ 1070: [SCOI2007]修车

    keyword:怎样建图?怎样转换网络流;

    如果想到网络流的话 ,就知道是费用流。

    然后怎么建图;

    我们有以下几个说明:

    1.加入源点,汇点

    2.加入每个源点和顾客连线的话,add(0,x,1,0)

    3:问题在于怎么在顾客和技术工人上连线:

       首先 我们知道 每个顾客可以和每个工人练一天cost(i,j)的线,但是有等待时间

      枚举等待时间即是在连接k*cost(i,j)的边,

      但是我们不是顾客连一个工人连N条线,工人再连线到汇点,因为我们知道一个工人只能做1个k*cost(i,j),举例来说 比如x这个技术工人只能第一下连y,第二下连z;

      所以一个巧妙的思路是:形成n+1 - n*m+n个新点,让1-n 个顾客 与这些点连。(其实一时半会说不出)

    总而言之,我们要做到 第一个顾客选择了弟i个技术工人的话 当且仅当联系一次。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<vector>
    #include<queue>
    #include<map>
    #define N 100000
    #define inf 0x3f3f3f
    using namespace std;
    
    struct edge
    {
        int v,next,flow,cost,cap;
    }e[N<<2];
    int head[N],tot;
    int pre[N],dis[N];
    int vis[N];
    int n,m;
    int cnt;
    
    void init()
    {
        tot=0;
        memset(head,-1,sizeof(head));
    }
    
    void add(int u,int v,int cap,int cost)
    {
        e[tot].v=v;
        e[tot].cap=cap;
        e[tot].cost=cost;
        e[tot].flow=0;
        e[tot].next=head[u];;
        head[u]=tot++;
        e[tot].v=u;
        e[tot].cap=0;
        e[tot].cost=-cost;
        e[tot].flow=0;
        e[tot].next=head[v];
        head[v]=tot++;
    }
    
    
    int spfa(int s,int t)
    {
        queue<int>q;
        for (int i=0;i<=cnt;i++)
        {
            dis[i]=inf;
            vis[i]=0;
            pre[i]=-1;
        }
    
        dis[s]=0;
        vis[s]=1;
        q.push(s);
    
        while (!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for (int i=head[u];i!=-1;i=e[i].next)
            {
                int v=e[i].v;
                if (e[i].cap>e[i].flow&&dis[v]>dis[u]+e[i].cost)
                {
                    dis[v]=dis[u]+e[i].cost;
                    pre[v]=i;
                    if (!vis[v])
                    {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return pre[t]!=-1;
    }
    
    int minCost(int s,int t,int &cost)
    {
        int flow=0;
            cost=0;
        while (spfa(s,t))
        {
            int Min=inf;
            for (int i=pre[t];i!=-1;i=pre[e[i^1].v])
                Min=min(Min,e[i].cap-e[i].flow);
    
            for (int i=pre[t];i!=-1;i=pre[e[i^1].v])
            {
                e[i].flow+=Min;
                e[i^1].flow-=Min;
                cost+=e[i].cost*Min;
            }
            flow+=Min;
        }
        return flow;
    }
    
    int mp[123][123];
    
    int main()
    {
       init();
       scanf("%d%d",&m,&n);
    
       int s=0;
       for (int i=1;i<=n;i++)
       for (int j=1;j<=m;j++)
       scanf("%d",&mp[i][j]);
    
       for (int i=1;i<=n;i++)
       add(s,i,1,0);
    
    
       cnt=n;
    
       for (int i=1;i<=m;i++)//主要是这里
       for (int k=1;k<=n;k++)
       {
           ++cnt;
           for (int j=1;j<=n;j++)
           add(j,cnt,1,k*mp[j][i]);
       }
    
       for (int i=n+1;i<=cnt;i++)
       add(i,cnt+1,1,0);
    
       cnt++;
       int t=cnt;
       int ans;
       int flow=minCost(s,t,ans);
       //printf("%d
    ",ans);
       printf("%.2lf
    ",(double) ans/n);
       return 0;
    
    }
    

      

      

  • 相关阅读:
    bzoj2599
    在Linux下配置jdk的环境变量
    liunx 命令大全
    Liunx下如何使用kettle
    Liunx 解压篇
    Linux下安装MySQL-5.7
    Linux文件权限查看及修改命令chmod,chown
    spring 驱动模式
    Struts2标签之Checkbox
    spring 注解的优点缺点
  • 原文地址:https://www.cnblogs.com/forgot93/p/4433723.html
Copyright © 2011-2022 走看看