zoukankan      html  css  js  c++  java
  • BZOJ 2879: [Noi2012]美食节

    同上道题的建模方法,不过这道题的数据较大,要用动态加边,判断每位厨师的最后一个点是否已用,如果用过,才添加下一个点

    CODE:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxn 1000
    #define maxm 180000
    #define inf 0x7fffffff
    using namespace std;
    struct edges{
        int to,cap,dist,next;
    }edge[maxm];
    int s,t,next[maxn],l;
    int addedge(int from,int to,int cap,int dist){
        l++;
        edge[l*2]=(edges){to,cap,dist,next[from]};
        edge[l*2+1]=(edges){from,0,-dist,next[to]};
        next[from]=l*2;next[to]=l*2+1;
        return 0;
    }
    bool b[maxn];
    int dist[maxn],node,way[maxn];
    queue<int> q;
    bool spfa(){
        for (int i=1;i<=node;i++) dist[i]=inf;
        memset(b,0,sizeof(b));
        dist[s]=0;
        q.push(s);
        while (!q.empty()){
            int u=q.front();q.pop();
            b[u]=0;
            for (int i=next[u];i;i=edge[i].next)
                if (edge[i].cap&&dist[u]+edge[i].dist<dist[edge[i].to]) {
                    dist[edge[i].to]=dist[u]+edge[i].dist;
                    way[edge[i].to]=i;
                    if (!b[edge[i].to]){
                        b[edge[i].to]=1;q.push(edge[i].to);
                    }
                }
        }
        if (dist[t]==inf) return 0;
        return 1;
    }
    int n,m,ti[50][110],last[110],cnt[110];
    int mcmf(){
        int cost=0;
        while (spfa()){
            cost+=dist[t];
            int x=t;
            while (x!=s){
                edge[way[x]].cap-=1;
                edge[way[x]^1].cap+=1;
                x=edge[way[x]^1].to;
            }
            for (int i=1;i<=m;i++)
                if (!edge[last[i]].cap) {
                    addedge(s,++node,1,0);
                    last[i]=l*2;cnt[i]++;
                    for (int j=1;j<=n;j++) addedge(node,2+j,1,cnt[i]*ti[j][i]);
                }
        }
        return cost;
    }
    int main(){
        scanf("%d%d",&n,&m);
        s=1;t=2;node=n+2+m;
        for (int i=1;i<=n;i++) {
            int x;
            scanf("%d",&x);
            addedge(i+2,t,x,0);
        }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++) scanf("%d",&ti[i][j]);
        for (int i=1;i<=m;i++) {
            cnt[i]=1;
            addedge(s,i+2+n,1,0);
            last[i]=l*2;
            for (int j=1;j<=n;j++) addedge(i+2+n,2+j,1,cnt[i]*ti[j][i]);
        }
        printf("%d ",mcmf());
        return 0;
    }
  • 相关阅读:
    河工大玲珑校赛重现の 饶学妹的比赛
    河工大玲珑杯校赛随笔
    河南省第四届ACM省赛(T1) 序号互换
    河南省第四届ACM省赛(T3) 表达式求值
    debian系统下安装ssh
    戴尔poweredge r730服务器配置以及系统安装
    win10环境下安装Ubantu双系统(超详解)
    debian服务器解决中文安装后出现乱码的问题
    debian系统下安装ssh
    如何在ubuntu上搭建hustoj?
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4348964.html
Copyright © 2011-2022 走看看