POJ(3034)(ACM Computer Factory)

链接:https://vjudge.net/problem/POJ-3436
思路:网络流题目,建图是一个难点,首先要用g[][]储存每个工厂的每种零件的情况,然后用G表示网络流里面的边,将一个工厂拆成两个点,分别对应生产厂和出产厂,两个点之间的流量为单位小时的生产值,建立一个源点和汇点,源点连向所需原料不含1的生产厂,流量为无穷,产品全为1的出产厂与汇点相连,流量为无穷,然后出产厂产品和生产厂的产品和原料对应相等且不为同一个点拆分出来的生产厂和出产厂之间连线,流量为无穷,即可建立好图。
至于路径,备份原图,然后生产厂到汇点+出产厂进行搜索,和原图流量不一致的地方即为路径。
代码:

/*************************************************************************
    > File Name: acmcomputerfactory.cpp
    > Author: 
    > Mail: 
    > Created Time: Wed 01 Aug 2018 07:34:32 PM CST
 ************************************************************************/

#include
#include
#include
#include
#include
using namespace std;

int n,m;
int G[120][120],GC[120][120];
const int INF = 0x3f3f3f3f;
int vis[120];
int Layer[120];
int g[120][120];
int q[120];

struct factory{
int a1,a2,a3;
};

bool countlayer(){
    memset(Layer,0xff,sizeof(Layer));
    Layer[0] = 0;
    deque q;
    q.push_back(0);
    while(!q.empty()){
        int v = q.front();
        q.pop_front();
        for(int i=0;i<=2*n+1;i++){
            if(G[v][i]>0&&Layer[i]==-1){
                Layer[i] = Layer[v] + 1;
                if(i==2*n+1)return true;
                q.push_back(i);
            }
    }
    }  
    return false;
}

int Dinic(){
    int i;
    int s;
    deque q;
    int MaxFlow = 0;
    while(countlayer()){
        q.push_back(0);
        memset(vis,0,sizeof(vis));
        vis[0] = 1;
        while(!q.empty()){
            int nd = q.back();
            if(nd==2*n+1){
                int nminc = INF;
                int nminc_vs = 0;
                for(i=1;i0){
                        if(nminc>G[vs][ve]){
                            nminc = G[vs][ve];
                            nminc_vs = vs;
                        }
                    }
                }
                MaxFlow+=nminc;
                for(i=1;i0&&Layer[i]==Layer[nd]+1&&!vis[i]){
                        vis[i] = 1;
                        q.push_back(i);
                        break;
                    }
                }
                if(i>2*n+1)
                q.pop_back();
            }
        }
    }
    return MaxFlow;
}

int main(){
    while(cin>>m>>n){
        memset(G,0,sizeof(G));
        memset(GC,0,sizeof(GC));

        for(int j=1;j<=n;j++){
        cin>>q[j];
        for(int i=1;i<=m;i++){
        cin>>g[j][i];
        }
            for(int i=1;i<=m;i++){
                cin>>g[j+n][i];
            }
        }
   //拆点
        for(int i=1;i<=n;i++){
            G[i][i+n] = q[i];
        }
//源点到不需要原料的生产厂
        for(int i=1;i<=n;i++){
            bool flag = true;
            for(int j=1;j<=m;j++){
                if(g[i][j]!=0&&g[i][j]!=2){
                    flag = false;
                    break;
                }
            }
                if(flag)G[0][i] = INF;
        }
//出产厂到匹配的生产厂
        for(int i=1;i<=n;i++){
            bool flag = true;
            for(int j=1;j<=m;j++){
                if(g[i+n][j]!=1){
                    flag = false;
                    break;
                }
            }
                if(flag)
                G[i+n][2*n+1] = INF;
        }
//出产厂到汇点
        for(int i=n+1;i<=2*n+1;i++){
            for(int j=1;j<=n;j++){
                bool flag = true;
                for(int k=1;k<=m;k++){
                    if(!(g[i][k]==g[j][k]||g[j][k]==2)){
                        flag = false;
                        break;
                    }
                }
                if(flag){
                    G[i][j] = INF;
                }
            }
        }
//备份
        for(int i=0;i<=2*n+1;i++){
            for(int j=0;j<=2*n+1;j++){
                GC[i][j] = G[i][j];
            }
        }
        cout< v;
//寻找路径
for(int i=n+1;i<=2*n+1;i++){
    for(int j=1;j<=n;j++){
        if(i-n!=j&&G[i][j]!=GC[i][j]){
            cnt++;
            factory tmp;
            tmp.a1 = i-n;
            tmp.a2 = j;
            tmp.a3 = GC[i][j] - G[i][j];
            v.push_back(tmp);
        }
    }
}
cout<

你可能感兴趣的:(POJ(3034)(ACM Computer Factory))