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

    题目链接

    bzoj2879: [Noi2012]美食节

    题解

    除了数据范围和修车一样
    对于没人没个要求拆点间图
    增光一条后更改下次增广费用
    然后要返向啊,不然就T了,好坑啊
    然后在西校写代码在东校调试,代码格式好鬼畜啊

    代码

    #include<queue> 
    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
     
    inline int read() { 
            int x = 0; 
            char c = getchar(); 
            while(c < '0' || c > '9')c = getchar(); 
            while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar();
            return x ; 
    }
    const int maxn = 100007 ; 
    struct Node {
            int next,u,flow,v,cost;
    }edge[maxn << 2 + 1]; int num = 1,head[maxn]; 
    inline void add_edge(int u,int v,int flow,int cost) { 
            edge[++ num].v = v;edge[num].u = u;edge[num].cost = cost,edge[num].flow = flow,edge[num].next = head[u];head[u] = num;
    } 
    inline void Add(int u,int v,int flow,int cost) {add_edge(u,v,flow,cost);add_edge(v,u,0,-cost);  } 
    int c[maxn],p[105][105],dis[maxn],pre[maxn];bool vis[maxn];  
    int que[maxn]; 
    int n,m,tot = 0,S,T,ans;
    bool spfa() {
           for(int i = 0;i <= T;++ i) vis[i] = 0,dis[i] = 0x3f3f3f3f;    
            dis[S] = 0;vis[S] = 1;
            int l = 0,r = 1;
        que[l] = S;
        while(l < r) {
                    int u = que[l ++];if(l == T) l = 0; 
                for(int i = head[u];i;i = edge[i].next) {
                        int v = edge[i].v;
                        if(edge[i].flow > 0 && dis[v] > dis[u] + edge[i].cost) {
                            pre[v] = i;
                            dis[v] = dis[u] + edge[i].cost; 
                            if(!vis[v]){que[r ++] = v,vis[v] = 1;if(r == T)r = 0;} 
                        }
                }   
                vis[u] = 0;
            }
            if(dis[T] == 0x3f3f3f3f) return false; 
            else return true; 
    } 
    void MCMF() { 
            while(spfa()) { 
                int MIN = 0x7fffffff,y,a,b;
                for(int i = pre[T];i;i = pre[edge[i].u])  
                    MIN = std::min(MIN,edge[i].flow); 
            for(int i = pre[T];i;i = pre[edge[i].u]) 
                    edge[i].flow -= MIN ,edge[i ^ 1].flow += MIN,ans += edge[i].cost * MIN;
                int x = edge[pre[T]].u; 
            Add(x + 1,T,1,0); 
            for(int i = 1;i <= n;++ i) {
                    Add(m * tot + i,x + 1,1,p[i][x / tot + 1] * (x % tot + 1)); 
                }       
        }
    } 
    int main() { 
            n = read(),m = read(); 
            S = 0;T = 100001;
            for(int i = 1;i <= n;++ i) c[i] = read(), tot += c[i]; 
            for(int i = 1;i <= n;++ i) {
            Add(S,i + tot * m,c[i],0);
                    for(int j = 1;j <= m;++ j) {
                    p[i][j] = read(); 
                Add(i + tot * m,(j - 1) * tot + 1,1,p[i][j]);       
            }
        }    
            for(int i = 1;i <= m;++ i) Add((i - 1) * tot + 1,T,1,0); 
            MCMF(); 
            printf("%d
    ",ans);  
        return 0; 
    }
    /*
    */
    
  • 相关阅读:
    图片处理中的Dithering技术
    网络I/O模型
    并发编程(二)
    并发编程(一)
    socket编程(二)
    socket编程(一)
    异常处理
    软件开发规范
    面向对象进阶
    多态与封装
  • 原文地址:https://www.cnblogs.com/sssy/p/9064057.html
Copyright © 2011-2022 走看看