• bzoj1449&&bzoj2895


    题解:

    S连每场比赛流量1费用0 
    每场比赛连参赛队流量1费用0 

    我们发现调整一次 由win,lose变为 win+1,lose-1的费用为 
    (C*(win+1)^2+D*(lose-1)^2) - (C*win^2+D*lose^2)=C*(2*win+1)-D*(2*lose-1) 
    暴力连边就可以了 
    最后的答案=最想费用流+最初假设所有队伍都输的收益

    代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=100005;
    int S,W,lose[N],sum[N],win[N],ans,C[N],D[N];
    int fi[N],n,t,cas,m,x,y,z,f[N],ne[N],num,zz[N],fl[N],gp[N],dist[N],pre[N],sl[N];
    void jb(int x,int y,int z,int s)
    {
        ne[num]=fi[x];
        fi[x]=num;
        zz[num]=y;
        sl[num]=z;
        fl[num++]=s;
        ne[num]=fi[y];
        fi[y]=num;
        zz[num]=x;
        sl[num]=0;
        fl[num++]=-s;
    }
    int spfa()
    {
        memset(dist,0x3f,sizeof dist);
        memset(pre,-1,sizeof pre);
        memset(gp,0,sizeof gp);
        memset(f,0,sizeof f);
        queue<int > Q;
        Q.push(S);
        dist[S]=0;
        while (!Q.empty())
         {
             int now=Q.front();
             Q.pop();
             f[now]=0;
             for (int i=fi[now];i!=-1;i=ne[i])
              if (sl[i]>0)
               {
                  int t=zz[i];
                  if (dist[t]>dist[now]+fl[i])
                   {
                       dist[t]=dist[now]+fl[i];
                       pre[t]=now;
                       gp[t]=i;
                       if (!f[t])
                        {
                            f[t]=1;
                            Q.push(t);
                        }
                   }
               }
         }
        if (pre[W]==-1)return 1;
        return 0; 
    }
    void Max_flow()
    {
        int cost=0,flow=0;
        while (!spfa())
         {
             int f=1e9;
             for (int i=W;i!=S;i=pre[i])
              f=min(f,sl[gp[i]]);
             cost+=f;
            flow+=dist[W]*f;
            for (int i=W;i!=S;i=pre[i])
             {
                 sl[gp[i]]-=f;
                 sl[gp[i]^1]+=f;
             } 
         }
        printf("%d
    ",flow+ans);
    }
    int main()
    {
        memset(fi,-1,sizeof fi);
        scanf("%d%d",&n,&m); 
        S=n+m+1,W=S+1;
        for (int i=1;i<=n;i++)scanf("%d%d%d%d",&win[i],&lose[i],&C[i],&D[i]);
        for (int i=1;i<=m;i++)
         {
            int x,y;
            scanf("%d%d",&x,&y);
            jb(S,n+i,1,0);
            jb(n+i,x,1,0);
            jb(n+i,y,1,0);
            sum[x]++,sum[y]++;
         }
        for (int i=1;i<=n;i++)lose[i]+=sum[i];
        for (int i=1;i<=n;i++)ans+=C[i]*win[i]*win[i]+D[i]*lose[i]*lose[i];
        for (int i=1;i<=n;i++)
         for (int j=1;j<=sum[i];j++)
          {
            jb(i,W,1,C[i]*(2*win[i]+1)-D[i]*(2*lose[i]-1));
            win[i]++;lose[i]--;
          }
        Max_flow();
    }
  • 相关阅读:
    Uva 11754(枚举+中国剩余定理)
    poj 1018(枚举+贪心)
    Uva 11021(概率)
    UVa 11426
    unittest(二)框架中的概念与断言
    unittest(一)IDE导出的代码分析
    Selenium(十五)cookie
    Selenium(十四)处理登录框的验证码
    Selenium(十三)调用js,控制浏览器的滚动条
    安装pytest
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8404066.html
Copyright © 2020-2023  润新知