zoukankan      html  css  js  c++  java
  • POJ3436 ACM Computer Factory【EK算法】

    题意:

    每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在,加工后会增加某些部分。且在单位时间内,每个机器的加工都有一个最大加工容量,求能得到的最大的流量,并且输出流经的所有路径。

    思路:

    最大流,EK算法。先建图,这里用邻接矩阵能比较简洁,由于每个机器(点)有权值,所以拆点,中间由与其权值想等的边连接,然后两两匹配,看是否能构成边。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int Max = 205;
    const int eMax = 5000;
    const int inf = 0x3f3f3f3f;
    
    struct
    {
        int w, in[11], out[11];
    }mac[Max];
    
    struct
    {
        int v, ini_w, w, re, next;
    }edge[eMax];
    
    int p, n, max_flow, num,k, edgeHead[Max],que[Max], pre[Max];
    bool vis[Max];
    
    void addedge(int u, int v, int w)
    {
        edge[k].v = v;
        edge[k].ini_w = edge[k].w = w;
        edge[k].next = edgeHead[u];
        edge[k].re = k+1;
        edgeHead[u] = k ++;
        edge[k].v = u;
        edge[k].ini_w = edge[k].w = 0;
        edge[k].next = edgeHead[v];
        edge[k].re = k-1;
        edgeHead[v] = k ++;
    }
    
    int bfs()
    {
        int head, tail, i, u, v;
        memset(vis, 0, sizeof(vis));
        head = tail = 1;
        que[tail ++] = 0;
        vis[0] = true;
        while(tail > head){
            u = que[head ++];
            for(i = edgeHead[u]; i != 0; i = edge[i].next){
                v = edge[i].v;
                if(!vis[v] && edge[i].w){
                    pre[v] = i;
                    if(v == 2*n+1) return true;
                    que[tail ++] = v;
                    vis[v] = true;
                }
            }
        }
        return false;
    }
    
    void end()
    {
        int u, p, sum = inf;
        for(u = 2*n+1; u != 0; u = edge[edge[p].re].v){
            p = pre[u];
            sum = min(sum, edge[p].w);
        }
        for(u = 2*n+1; u != 0; u = edge[edge[p].re].v){
            p = pre[u];
            edge[p].w -= sum;
            edge[edge[p].re].w += sum;
        }
        max_flow += sum;
    }
    
    int main()
    {
        int i, j, u, m;
        bool flag;
        cin>>p>>n;
        for(k = 1, i = 1; i <= n; i ++)
        {
            cin>>mac[i].w;
            flag = true;
            for(j = 0; j < p; j ++)
            {
                cin>>mac[i].in[j];
                if(mac[i].in[j] == 1) flag = false;   //  这里要注意,0020也可以连源点,与汇点不同!
            }
            if(flag) addedge(0, i, inf);
            flag = true;
            for(j = 0; j < p; j ++)
            {
                cin>>mac[i].out[j];
                if(mac[i].out[j] != 1) flag = false;
            }
            if(flag) addedge(n+i, 2*n+1, inf);
        }
        for(i = 1; i <= n; i ++)
        {
            addedge(i, n+i, mac[i].w);                //  拆点。
            for(j = 1; j <= n; j ++)
            {
                if(i == j) continue;
                flag = true;
                for(m = 0; m < p; m ++)
                    if(mac[j].in[m] != 2 && mac[j].in[m] != mac[i].out[m])
                    {
                        flag = false;
                        break;
                    }
                if(flag) addedge(n+i, j, inf);
            }
        }
        max_flow = 0, num = 0;
        while(bfs()) end();
        for(u = n+1; u < 2*n+1 ; u ++)                //  流经路径的输出,用邻接矩阵会更简洁。
            for(i = edgeHead[u]; i != 0; i = edge[i].next)
                if(edge[i].v > 0 && edge[i].v <= n && edge[i].ini_w > edge[i].w)
                    num ++;
        cout<<max_flow<<" "<<num<<endl;
        for(u = n+1; u < 2*n+1 ; u ++)
            for(i = edgeHead[u]; i != 0; i = edge[i].next)
                if(edge[i].v > 0 && edge[i].v <= n && edge[i].ini_w > edge[i].w)
                    cout<<u-n<<" "<<edge[i].v<<" "<<edge[i].ini_w - edge[i].w<<endl;
        return 0;
    }
  • 相关阅读:
    ReactiveCocoa详解
    你真的了解iOS的深浅拷贝吗?
    Spring Boot中使用Swagger2构建强大的RESTful API文档
    Spring Boot Logback应用日志
    HTTP与私有二进制协议之间的区别
    Linux常见命令
    solr云的简单搭建(了解)
    项目开发与总结
    垂直分库所带来的问题和解决方法
    水平分库分表的关键问题及解决思路
  • 原文地址:https://www.cnblogs.com/darklights/p/7668466.html
Copyright © 2011-2022 走看看