POJ 3426 ACM Computer Factory 据说是拆点最大流= =。。不知道神马是拆点= =

题目连接:http://poj.org/problem?id=3436

英语不好,直接在网上搜的题意、、、很详细

题意:电脑工厂有N台机器,每台机器对半成品电脑进行加工。每个电脑由P个部件组成,用0和1表示某部件是否已存在

(1表示存在了)。

每台机器对加工的电脑都是有要求的,只有满足要求,才能进入机器进行加工。

机器对电脑部件的要求用0,1,2表示,输入的P个数中,第i个数为ai,ai=0表示该半成品电脑不能有部件i,ai=1表示

该半成品必须已有部件i(即1),ai=2表示有没有此部件都无关系。

进入机器加工后的电脑出来后所含部件情况用P个数字(0或1)表示。

输入:P和N,接下来N行介绍N个机器,第一个数Q,表示单位时间此机器能加工的电脑数(我是这么理解的),接下来两

个数串,第一个P个数(0,1,2序列)表示该机器的对电脑所含部件的要求,第二个P个数(0,1序列)表示经该机器加工

后,输出的电脑所含部件的情况。

输出:单位时间能生产最多的电脑数,然后输出必须给N台机器间连接的生产线数。每行输出生产线的情况。起点U、终

点V,以及它们的权值W。

 

坑爹的一点是如果大家要用EK去做的话要用stack来进行搜索不能用queue。我也不知道为神马,discuss里面有。

一开始WA n遍,后来看了一组测试样例过了。注意与源点连接的条件。当然这题需要虚拟源点跟汇点。

代码:

View Code
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stack>

#include <algorithm>
#define maxn 10050
using namespace std;
struct machine
{
    int pre[15],beh[15],out;
}node[210];
int cap[210][210],pre[210];

int ans[210][210] = {0};

int pipei(int i,int j,int m)
{
    int ii;
    for(ii = 1;ii <= m;ii++)
    {
        if(node[i].pre[ii] != 2)
        {
            if(node[i].pre[ii] == node[j].beh[ii])
            continue;
            else
            return 0;
        }
    }
    return 1;
}
int is_yuan(int i,int n)
{
    int j;
    for(j = 1;j <= n;j++)
    if(node[i].pre[j] == 1)
    return 0;

    return 1;
}

int flow[150][150],temp[150];
int ek(int n)
{
    int i,j;
    stack<int>q;

    int u,v,nu,nv;
    nu = nv = 0;
    memset(flow,0,sizeof(flow));
    int f = 0;
    for(;;)
    {
        memset(temp,0,sizeof(temp));
        q.push(0);
        temp[0] = maxn;
        while(!q.empty())
        {

            u = q.top();
            q.pop();
            for(v = 1;v <= n;v++)
            if(!temp[v] &&cap[u][v] > flow[u][v])
            {
                pre[v] = u;
                q.push(v);
                if(cap[u][v]-flow[u][v] < temp[u])
                temp[v] = cap[u][v]-flow[u][v],nu = u,nv = v;
                else
                temp[v] = temp[u];
            }
        }
        if(temp[n] == 0)
        break;
        ans[nu][nv] += temp[n];
        for(v = n;v != 0 ;v = pre[v])
        {
            flow[pre[v]][v] += temp[n];
            flow[v][pre[v]] -= temp[n];

        }

        f += temp[n];

    }
    return f;
}

int is_hui(int i,int n)
{
    int j;

    for(j = 1;j <= n;j++)
    if(node[i].beh[j] != 1)
    return 0;

    return 1;
}

int main()
{
    int i,j,n,p,count = 0;
    scanf("%d %d",&p,&n);
    memset(cap,0,sizeof(cap));
    for(i = 1;i <= n;i++)
    {
        scanf("%d",&node[i].out);
        for(j = 1;j <= p;j++)
        scanf("%d",&node[i].pre[j]);

        for(j = 1;j <= p;j++)
        scanf("%d",&node[i].beh[j]);
    }

    for(i =1;i <= n;i++)
        if(is_yuan(i,p))
        cap[0][i] = node[i].out;
    for(i =1;i <= n;i++)
        if(is_hui(i,p))
        cap[i][n+1] = node[i].out;

    for(i =1;i <= n;i++)
    {
        for(j = 1;j <= n;j++)
        {
            if(i != j &&pipei(i,j,p))
            cap[j][i] = node[j].out;
        }
    }

    int res;
    res = ek(n+1);
    printf("%d",res);
    int u;
    for(i = 1;i <= n;i++)
    {
        for(j = 1;j <= n;j++)
        if(flow[i][j] > 0)
        count++;
    }
    if(res)
    {

        cout<<" "<<count<<endl;
        for(i = 1;i <= n;i++)
        {
            for(j = 1;j <= n;j++)
            if(flow[i][j] > 0)
            cout<<i<<" "<<j<<" "<<flow[i][j]<<endl;
        }
    }
    else
    printf(" %d\n",count);
    return 0;
}

 

posted @ 2013-01-18 17:03  某某。  阅读(384)  评论(0编辑  收藏  举报