zoukankan      html  css  js  c++  java
  • [NOI2012]美食节

    题解:

    很经典的网络流

    对于每个厨师拆点分开统计 1倍 2倍 3倍

    n(mp)^2 有点大

    动态加边

    即对于每个厨师有了i才会有i+1

    不过好像还是有点卡常??

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 1e9
    #define N 2000000
    struct re{
        int a,b,c,from,flow,cost;
    }a[N];
    int head[N],l,d[N],p[N],aa[N],dy1[N],dy2[N],tt[1000][1000],cnt;
    int n,m,s,t,maxa[N];
    bool inq[N];
    void arr(int x,int y,int z,int flow,int cost,int xx,int yy)
    {
        a[++l].a=head[x];
        a[l].b=y;
        a[l].c=z;
        head[x]=l;
        a[l].flow=flow;
        a[l].cost=cost;
        a[l].from=x;
        dy1[l]=xx;
        dy2[l]=yy;
    }
    bool bellmanford(int &flow,int &cost)
    {
        for (int i=1;i<=t;i++) d[i]=INF;
        memset(inq,0,sizeof(inq));
        d[s]=0; inq[s]=1; p[s]=0; aa[s]=INF;
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int x=q.front(); q.pop(); inq[x]=0;
            int u=head[x];
            while (u)
            {
                int v=a[u].b;
                if (a[u].c>a[u].flow&&d[v]>d[x]+a[u].cost)
                {
                    d[v]=d[x]+a[u].cost;
                    p[v]=u;
                    aa[v]=min(aa[x],a[u].c-a[u].flow);
                    if (!inq[v]) q.push(v),inq[v]=1;
                }
                u=a[u].a;
            }
        }
        if (d[t]==INF) return(0);
        flow+=aa[t];
        cost+=d[t]*aa[t];
        int x=t;
        while (x!=s)
        {
            int u=p[x];
            a[u].flow+=aa[t];
            if (u%2) a[u+1].flow-=aa[t];
            else a[u-1].flow-=aa[t];
            if (dy2[u]==maxa[dy1[u]])
            {
              int y=dy1[u];
              maxa[y]++;
              cnt++;
              for (int i=1;i<=n;i++)
              {
                arr(i,cnt,1,0,tt[i][y]*maxa[y],y,maxa[y]);
                arr(cnt,i,0,0,-tt[i][y]*maxa[y],y,maxa[y]);
              }
              arr(cnt,t,1,0,0,0,0);
              arr(t,cnt,0,0,0,0,0);
            }
            //cout<<a[u].from<<" "<<a[u].b<<" "<<a[u].cost<<" "<<a[u].flow<<endl;
            x=a[u].from;
        }
        //cout<<endl;
        return 1;
    }
    int flow,cost;
    void mincost()
    {
        while (bellmanford(flow,cost));
    }
    int pp[N];
    int main()
    {
        std::ios::sync_with_stdio(false);
        cin>>n>>m;
        int sum=0;
        for (int i=1;i<=n;i++)
        {
            cin>>pp[i]; sum+=pp[i];
         }
        for (int i=1;i<=n;i++)
          for (int j=1;j<=m;j++)
            cin>>tt[i][j];
        s=0; t=n+m*sum+1;
        for (int i=1;i<=n;i++)
          arr(s,i,pp[i],0,0,0,0),arr(i,s,0,0,0,0,0);
        maxa[0]=INF;
        for (int i=1;i<=n;i++)
          for (int j=1;j<=m;j++)
            {
              maxa[j]=1;
              cnt=n+j;
              arr(i,cnt,1,0,tt[i][j],j,1);
              arr(cnt,i,0,0,-tt[i][j],j,1);
            }
        for (int i=1;i<=m;i++)
        {
           cnt=n+i;
           arr(cnt,t,1,0,0,0,0);
           arr(t,cnt,0,0,0,0,0);
        }
        cnt=n+m;
    /*    for (int i=1;i<=l;i++)
        {
            cout<<a[i].b<<" "<<a[i].from<<" "<<a[i].c<<" "<<a[i].cost<<endl;
        } */
        mincost();
        cout<<cost<<endl;
        return 0;
    }
  • 相关阅读:
    互联网协议入门详解(转)
    文件流结尾的EOF详解
    数字签名是什么?
    SSL/TLS协议运行机制的概述(转)
    图解SSL/TLS协议(转)
    RSA算法原理(转)
    HTML代码简写法:Emmet和Haml(转)
    HTML Email 编写指南(转)
    PHP CodeBase: 判断用户是否手机访问
    Spring Data JPA之Derived query
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8878460.html
Copyright © 2011-2022 走看看