• 洛谷2050 BZOJ2897美食节题解


    放个链接

    BZ链接

    其实这题就是修车的加强版,做法差不多,还是对于每个厨师进行拆点

    可是这样强行建图跑网络流会T飞

    我们发现,如果一个厨师没有做倒数第x到菜,他一定不会做倒数第x+1到菜

    我们的每次增广表示有厨师的倒数第k道菜做了y,这样我们把这位厨师的倒数做k+1道菜的边连起来

    动态加边

    连边是注意每个点的意思是什么

    # include<iostream>
    # include<cstdio>
    # include<algorithm>
    # include<cmath>
    # include<cstring>
    # include<queue>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int mn = 100005;
    int c[45][105],p[45];
    struct edge{int to,next,flow,cost;};
    edge e[3000005];
    int head[mn],edge_max=1;
    void add(int x,int y,int z,int k)
    {
        //printf("%d %d %d %d
    ",x,y,z,k);
        e[++edge_max].to=y;
        e[edge_max].flow=z;
        e[edge_max].cost=k;
        e[edge_max].next=head[x];
        head[x]=edge_max;
    }
    int n,m,sum;
    int dis[mn],pe[mn],pv[mn],ansc,ansf;
    bool vis[mn];
    queue<int> q;
    bool spfa(int x,int y)
    {
        memset(dis,0x3f,sizeof(dis));
        dis[x]=0;
        q.push(x);
        while(!q.empty())
        {
            int u=q.front();
            vis[u]=0;
            q.pop();
            for(int i=head[u];i;i=e[i].next)
            {
                if(e[i].flow>0 && e[i].cost+dis[u]<dis[e[i].to])
                {
                    dis[e[i].to]=dis[u]+e[i].cost;
                    pv[e[i].to]=u;
                    pe[e[i].to]=i;
                    if(!vis[e[i].to])
                    {
                        vis[e[i].to]=1;
                        q.push(e[i].to);
                    }
                }
            }
        }
        //for(int i=0;i<=y;i++)
        //printf("%d ",dis[y]);
        return dis[y]<inf;
    }
    void max_flow(int x,int y)
    {
        int kflow,a,b;//a表示厨师编号
        while(spfa(x,y))
        {
            //printf("%d %d
    ",ansc,ansf);
            kflow=inf;
            for(int i=y;i!=x;i=pv[i])
                kflow=min(kflow,e[pe[i]].flow);
            a=(pv[y]-1)/sum+1;
            b=pv[y]%sum+1;
            ansf+=kflow;
            ansc+=kflow*dis[y];
            for(int i=y;i!=x;i=pv[i])
            {
                e[pe[i]].flow-=kflow;
                e[pe[i]^1].flow+=kflow;
                //ansc+=kflow*e[pe[i]].cost;
            }
            for(int i=1;i<=n;i++)
                add(i+m*sum,(a-1)*sum+b,1,c[i][a]*b),add((a-1)*sum+b,i+m*sum,0,-c[i][a]*b);
        }
    }
    int main()
    {
        int st=0;
        //freopen("testdata.in","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&p[i]),sum+=p[i];
        int en=sum*m+n+1;
       // printf("%d
    ",en);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            scanf("%d",&c[i][j]);
        for(int i=1;i<=n;i++)
            add(st,i+m*sum,p[i],0),add(i+m*sum,st,0,0);
        for(int i=1;i<=m*sum;i++)
            add(i,en,1,0),add(en,i,0,0);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
            add(j+m*sum,(i-1)*sum+1,1,c[j][i]),add((i-1)*sum+1,j+m*sum,0,-c[j][i]);
        max_flow(st,en);
        printf("%d",ansc);
        return 0;
    }
  • 相关阅读:
    AJAX中所谓的异步
    前端性能优化方案
    文字超出隐藏
    创建值的两种方式及其区别
    单例模式
    自定义数据属性
    时间字符串的处理
    日期函数及时钟案例
    很low的四位验证码实现
    使用Ajax发送http请求(get&post请求)--转载
  • 原文地址:https://www.cnblogs.com/logeadd/p/9555130.html
Copyright © 2020-2023  润新知