• bzoj2055


    题解:

    似乎是放在费用流里的

    然而是有上下界的网络流QAQ

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=40005;
    int n,m,x,mincost,s,t,S,ss,tt,tot,fi[N],ne[N],zz[N],sl[N],c[N];
    int dis[N],last[N],d[N],vis[N];
    queue <int> q;
    void jb(int x,int y,int cap,int z)
    {
        ne[++tot]=fi[x];
        fi[x]=tot;
        zz[tot]=y;
        sl[tot]=cap;
        c[tot]=z;
        ne[++tot]=fi[y];
        fi[y]=tot;
        zz[tot]=x;
        sl[tot]=0;
        c[tot]=-z;
    }
    int addflow(int s,int t)
    {
        int now=t,ans=1e9;
        while (now!=s)
         {
            ans=min(ans,sl[last[now]]);
            now=zz[last[now]^1];
         }
        now=t;
        while (now!=s)
         {
            sl[last[now]]-=ans;
            sl[last[now]^1]+=ans;
            now=zz[last[now]^1];
         }
        return ans;
    }
    int spfa(int s,int t)
    {
        memset(dis,127,sizeof(dis));
        dis[s]=0;
        memset(vis,0,sizeof(vis));
        vis[s]=1;
        while (!q.empty())q.pop();
        q.push(s);
        while (!q.empty())
         {
            int now=q.front();q.pop();
            vis[now]=0;
            for (int i=fi[now];i!=-1;i=ne[i])
             if (dis[zz[i]]>dis[now]+c[i]&&sl[i])
              {
                dis[zz[i]]=dis[now]+c[i];
                last[zz[i]]=i;
                if (!vis[zz[i]])
                 {
                    vis[zz[i]]=1;
                    q.push(zz[i]);
                 }
              }
         }
        if (dis[t]>1e9) return 0;
        int flow=addflow(s,t);
        mincost+=flow*dis[t];
        return 1;
    }
    int main()
    {
        tot=-1;
        memset(fi,-1,sizeof(fi));
        scanf("%d%d",&n,&m);
        S=n+n+1,s=S+1,t=s+1;ss=t+1,tt=ss+1;
        d[s]-=m,d[S]+=m;
        for (int i=1;i<=n;i++)
         {
            scanf("%d",&x);
            jb(S,i,1e9,0);
            jb(n+i,t,1e9,0);
            d[i]-=x,d[n+i]+=x;
         }
        for (int i=1;i<n;i++)
         for (int j=i+1;j<=n;j++)
          {
            scanf("%d",&x);
            if (x==-1) continue;
            jb(n+i,j,1e9,x);
          }
        for (int i=1;i<=t;i++)
         {
            if (d[i]>0)jb(ss,i,d[i],0);
            if (d[i]<0)jb(i,tt,-d[i],0);
         }
        jb(t,s,1e9,0);
        while (spfa(ss,tt));
        printf("%d
    ",mincost);
    }
  • 相关阅读:
    TreeView使用集锦
    net 下安装、调试的常见问题与错误及解决方法 [转]
    Oracle中使用同义词
    再推荐两个blog和一首好歌
    一点感慨
    推荐一个blog和一个工具
    买书了
    第一次做饭
    ORA00911错误及解决方法
    C#3.0美文收集
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8480602.html
Copyright © 2020-2023  润新知