• poj3436 ACM Computer Factory, 最大流,输出路径


    POJ 3436 ACM Computer Factory

    电脑公司生产电脑有N个机器。每一个机器单位时间产量为Qi。


    电脑由P个部件组成,每一个机器工作时仅仅能把有某些部件的半成品电脑(或什么都没有的空电脑)变成有还有一些部件的半成品电脑或完整电脑(也可能移除某些部件)。求电脑公司的单位时间最大产量,以及哪些机器有协作关系,即一台机器把它的产品交给哪些机器加工。


    Sample input
    3 4
    15  0 0 0  0 1 0
    10  0 0 0  0 1 1
    30  0 1 2  1 1 1
    3    0 2 1  1 1 1

    Sample output
    25 2
    1 3 15
    2 3 10

    输入:电脑由3个部件组成。共同拥有4台机器,1号机器产量15, 能给空电脑加上2号部件,2号 机器能给空电脑加上2号部件和3号部件, 3号机器能把有1个2号部件和3号部件有无均可的电脑变成成品(每种部件各有一个)


    输出:单位时间最大产量25,有两台机器有协作关系。
    1号机器单位时间内要将15个电脑给3号机器加工
    2号机器单位时间内要将10个电脑给3号机器加工



    数据规模非常小,用EdmondsKarp就能够了。主要题目不仅要求最大流的值还要输出有流流过的边。

    细致想一想。这题不用拆点!


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 60;
    const int inf = 0x7fffffff;
    
    struct Edge {
        int from,to,cap,flow;
        Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f) {}
    };
    struct EdmondsKarp {
        int n,m;
        vector<Edge> edges;
        vector<int> G[maxn];
        int p[maxn];
        int a[maxn];
    
        void init(int n)
        {
            this->n=n;
            for(int i=0; i<n; i++)
                G[i].clear();
            edges.clear();
        }
    
        void AddEdge(int from,int to,int cap)
        {
            edges.push_back(Edge(from,to,cap,0));
            edges.push_back(Edge(to,from,0,0));
            m=edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
    
        int Maxflow(int s,int t)
        {
            int flow=0;
            while(true) {
                memset(a,0,sizeof(a));
                queue<int> Q;
                Q.push(s);
                a[s]=inf;
                while(!Q.empty()) {
                    int x=Q.front();
                    Q.pop();
                    for(int i=0; i<G[x].size(); i++) {
                        Edge &e=edges[G[x][i]];
                        if(!a[e.to]&&e.cap>e.flow) {
                            a[e.to]=min(a[x],e.cap-e.flow);
                            p[e.to]=G[x][i];
                            Q.push(e.to);
                            if(e.to==t)
                                break;
                        }
                    }
                    if(a[t])break;
                }
                if(!a[t])break;
                for(int u=t; u!=s; u=edges[p[u]].from) {
                    edges[p[u]].flow+=a[t];
                    edges[p[u]^1].flow-=a[t];
                }
                flow+=a[t];
            }
            return flow;
        }
    };
    
    EdmondsKarp solver;
    
    int P, N;
    int w[maxn], in[maxn][12], out[maxn][12];
    
    int print[maxn][5], cnt;
    int main()
    {
        int i, j;
        bool flag;
        while(~scanf("%d%d", &P, &N)) {
            int s = 0, t = N+1;
            solver.init(N+2);
            for(int i=1; i<=N; ++i) {
                scanf("%d", &w[i]);
                flag = true;
                for(j=0; j<P; ++j) {
                    scanf("%d", &in[i][j]);
                    if(in[i][j]==1) flag = false;
                }
                if(flag) solver.AddEdge(s, i, w[i]);
    
                flag = true;
                for(j=0; j<P; ++j) {
                    scanf("%d", &out[i][j]);
                    if(out[i][j]!=1) flag = false;
                }
                if(flag) solver.AddEdge(i, t, w[i]);
            }
            for(i=1; i<=N; ++i) {
                for(j=1; j<=N; ++j) {
                    if(i==j) continue;
                    flag = true;
                    for(int k=0; k<P; ++k)
                        if(out[i][k] + in[j][k] == 1) {
                            flag = false;
                            break;
                        }
                    if(flag) solver.AddEdge(i, j, min(w[i], w[j]));
                }
            }
    
            printf("%d ", solver.Maxflow(s, t));
            cnt = 0;
            for(i=1; i<=N; ++i)
                for(j=0; j<solver.G[i].size(); ++j)
            {
                Edge &e = solver.edges[solver.G[i][j]];
                if(e.flow>0 && e.to != t && e.from != s)
                {
                    print[cnt][0] = e.from;
                    print[cnt][1] = e.to;
                    print[cnt++][2] = e.flow;
                }
            }
            printf("%d
    ", cnt);
            for(i=0; i<cnt; ++i)
                printf("%d %d %d
    ", print[i][0],print[i][1],print[i][2]);
        }
        return 0;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    


  • 相关阅读:
    今天早上打算去菜市场看看是否开张
    昨天晚上雨岳阳通话后,晚上睡着肚子咕咕叫
    已经一周没有开锅了
    今天早上6:00起来,每天晚上回来6点多已经天黑
    其实值班也是一个说法
    感觉每天虽然没有做什么,但是就是觉得睡不够
    现在进入秋季,上海也是在20度左右
    mysql 下 计算 两点 经纬度 之间的距离 含具体sql语句
    java解析xml的几种方式
    myeclipse安装svn插件的多种方式
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7356112.html
Copyright © 2020-2023  润新知