• bzoj 1070 修车 —— 费用流


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1070

    需要考虑前面修的车对后面等待的车造成的时间增加;

    其实可以从每个人修车的顺序考虑,如果这辆车作为最后一辆被一个人修,那么它对后面的车无影响,而每提前一位,影响时间就增加一份;

    也就是如果确定一辆车是第几个被修的,那么它的影响就可以单独确定;

    费用流的选边策略是先选费用小的,再选费用大的,正可以对应这个过程;

    所以把每个人拆成 n 个点表示修车顺序,然后车向对应的点连对应边权的边即可。

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int const xn=605,xm=80005,inf=1e9;
    int n,m,hd[xn],ct=1,to[xm],nxt[xm],w[xm],c[xm],S,T;
    int dis[xn],pre[xn],inc[xn];
    bool vis[xn];
    queue<int>q;
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    int Min(int x,int y){return x<y?x:y;}
    void ade(int x,int y,int z,int f){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct; w[ct]=z; c[ct]=f;}
    void add(int x,int y,int z,int f){ade(x,y,z,f); ade(y,x,-z,0);}
    int id(int x,int tp)
    {
      if(!tp)return m*n+x;
      return (x-1)*n+tp;
    }
    bool bfs()
    {
      for(int i=S;i<=T;i++)vis[i]=0;
      for(int i=S;i<=T;i++)dis[i]=inf;
      dis[S]=0; q.push(S); vis[S]=1; inc[S]=inf;//inc!!
      while(q.size())
        {
          int x=q.front(); q.pop(); vis[x]=0;
          for(int i=hd[x],u;i;i=nxt[i])
        if(dis[u=to[i]]>dis[x]+w[i]&&c[i])
          {
            dis[u]=dis[x]+w[i]; pre[u]=i;
            inc[u]=Min(inc[x],c[i]);
            if(!vis[u])vis[u]=1,q.push(u);
          }
        }
      return dis[T]!=inf;
    }
    void up()
    {
      int x=T;
      while(x!=S)
        {
          int i=pre[x];
          c[i]-=inc[T]; c[i^1]+=inc[T];
          x=to[i^1];
        }
    }
    int main()
    {
      m=rd(); n=rd(); S=0; T=id(n,0)+1;
      for(int j=1;j<=n;j++)
        for(int i=1,x;i<=m;i++)
          {
        x=rd();
        for(int k=1;k<=n;k++)
          add(id(j,0),id(i,k),k*x,1);
          }
      for(int j=1;j<=n;j++)add(S,id(j,0),0,1);
      for(int i=id(1,1);i<=id(m,n);i++)add(i,T,0,1);
      int ans=0;
      while(bfs())ans+=dis[T]*inc[T],up();
      printf("%.2f
    ",1.0*ans/n);
      return 0;
    }
  • 相关阅读:
    SharePoint客户端开发:增加用户信息到用户信息列表
    Query Options的一些用法(5):日历的处理
    User Profile Service卡在Starting的解决方法
    python enumerate用法
    希腊字母的发音
    在Linux下安装go语言环境
    Gradle的安装与使用
    学习正太分布及极差、移动极差、方差、标准差等知识点
    招聘还是炫耀,设计模式是装逼利器?
    Silverlight + RIA Service的SUID的实例。
  • 原文地址:https://www.cnblogs.com/Zinn/p/10155038.html
Copyright © 2020-2023  润新知