• 【二分答案】【最大流】bzoj3993 [Sdoi2015]星际战争


    二分Time,
    S->炮[i]:Time*b[i]

    炮[i]->机器人[i]:INF

    机器人[i]->T:a[i]。

    判断是否满流。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define N 51
    #define EPS 0.000001
    #define INF 2147483647.0
    typedef double db;
    queue<int>q;
    int n,m,a[N],b[N],sumv;
    bool can[N][N];
    int v[2*N*(N+1)],en,first[N*2+3],next[2*N*(N+1)];
    db cap[2*N*(N+1)];
    void AddEdge(int U,int V,db W)
    {
        v[en]=V; cap[en]=W; next[en]=first[U]; first[U]=en++;
        v[en]=U; cap[en]=0; next[en]=first[V]; first[V]=en++;
    }
    int S,T,nn;
    int d[N*2+3],cur[N*2+3];
    bool bfs()
    {
        memset(d,-1,sizeof(int)*(nn+1));
        d[S]=0;
        q.push(S);
        while(!q.empty())
          {
            int U=q.front(); q.pop();
            for(int i=first[U];i!=-1;i=next[i])
              if(d[v[i]]==-1&&cap[i]>EPS)
                {
                  d[v[i]]=d[U]+1;
                  q.push(v[i]);
                }
          }
        return d[T]!=-1;
    }
    db dfs(int U,db a)
    {
        if(U==T||a<=EPS)
          return a;
        db Flow=0.0,f;
        for(int &i=cur[U];i!=-1;i=next[i])
          if(d[v[i]]==d[U]+1&&(f=dfs(v[i],min(a,cap[i])))>EPS)
            {
              cap[i]-=f;
              cap[i^1]+=f;
              Flow+=f;
              a-=f;
              if(a<=EPS)
                break;
            }
        if(Flow<=EPS) d[U]=-1;
        return Flow;
    }
    db MaxFlow()
    {
        db Flow=0.0,tmp;
        while(bfs())
          {
            memcpy(cur,first,sizeof(int)*(nn+1));
            while((tmp=dfs(S,INF))>EPS) Flow+=tmp;
          }
        return Flow;
    }
    bool check(db Lim)
    {
        memset(first,-1,sizeof(int)*(nn+1));
        en=0;
        for(int i=1;i<=m;++i)
          AddEdge(S,1+i,Lim*(db)b[i]);
        for(int i=1;i<=n;++i)
          AddEdge(1+m+i,T,(db)a[i]);
        for(int i=1;i<=m;++i)
          for(int j=1;j<=n;++j)
            if(can[i][j])
              AddEdge(1+i,1+m+j,INF);
        return fabs(MaxFlow()-(db)sumv)<=EPS?1:0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
          {
            scanf("%d",&a[i]);
            sumv+=a[i];
          }
        for(int i=1;i<=m;++i) scanf("%d",&b[i]);
        for(int i=1;i<=m;++i)
          for(int j=1;j<=n;++j)
            scanf("%d",&can[i][j]);
        S=1; T=nn=m+n+2;
        db l=0.0,r=5000000.0;
        while(r-l>EPS)
          {
            db mid=(l+r)/2.0;
            if(check(mid))
              r=mid-EPS;
            else
              l=mid+EPS;
          }
        printf("%lf
    ",l);
        return 0;
    }
  • 相关阅读:
    产品方法论
    elastic search语句
    计算机科学发展的动力
    理论计算机科学学习网站
    算法学习 howto
    人工智能和机器学习 AI&ML howto
    Deep Learning 和 Knowledge Graph howto
    LISP语言学习资源
    Turing Year 2012
    如何做好计算机科学研究
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4430076.html
Copyright © 2020-2023  润新知