码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3436 网络最大流加打印路径

时间:2015-04-11 11:44:41      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

ACM Computer Factory
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5689   Accepted: 1954   Special Judge

Description

As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That is why all these computers are historically produced at the same factory.

Every ACM computer consists of P parts. When all these parts are present, the computer is ready and can be shipped to one of the numerous ACM contests.

Computer manufacturing is fully automated by using N various machines. Each machine removes some parts from a half-finished computer and adds some new parts (removing of parts is sometimes necessary as the parts cannot be added to a computer in arbitrary order). Each machine is described by its performance (measured in computers per hour), input and output specification.

Input specification describes which parts must be present in a half-finished computer for the machine to be able to operate on it. The specification is a set of P numbers 0, 1 or 2 (one number for each part), where 0 means that corresponding part must not be present, 1 — the part is required, 2 — presence of the part doesn‘t matter.

Output specification describes the result of the operation, and is a set of P numbers 0 or 1, where 0 means that the part is absent, 1 — the part is present.

The machines are connected by very fast production lines so that delivery time is negligibly small compared to production time.

After many years of operation the overall performance of the ACM Computer Factory became insufficient for satisfying the growing contest needs. That is why ACM directorate decided to upgrade the factory.

As different machines were installed in different time periods, they were often not optimally connected to the existing factory machines. It was noted that the easiest way to upgrade the factory is to rearrange production lines. ACM directorate decided to entrust you with solving this problem.

Input

Input file contains integers P N, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integers Qi Si,1 Si,2...Si,P Di,1 Di,2...Di,P, where Qi specifies performance, Si,j— input specification for part j, Di,k — output specification for part k.

Constraints

1 ≤ P ≤ 10, 1 ≤ N ≤ 50, 1 ≤ Qi ≤ 10000

Output

Output the maximum possible overall performance, then M — number of connections that must be made, then M descriptions of the connections. Each connection between machines A and B must be described by three positive numbers A B W, where W is the number of computers delivered from A to B per hour.

If several solutions exist, output any of them.

Sample Input

Sample input 1
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 input 2
3 5
5   0 0 0  0 1 0
100 0 1 0  1 0 1
3   0 1 0  1 1 0
1   1 0 1  1 1 0
300 1 1 2  1 1 1
Sample input 3
2 2
100  0 0  1 0
200  0 1  1 1

Sample Output

Sample output 1
25 2
1 3 15
2 3 10
Sample output 2
4 5
1 3 3
3 5 3
1 2 1
2 4 1
4 5 1
Sample output 3
0 0


这题就两个注意的地方,如果他要求的输入的电脑状态是0 1 0,那么你就不能把1 1 0放进去,这点我被坑的很惨,然后还有一个就是dinic算法中的反向流其实就是路径,这点很容易想明白的。
下附ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<climits>
using namespace std;
struct Comp
{
    int need[11];
    int give[11];
    int num;
}comp[60];
int s[60];
int t[60];
int pre[60];
int sum;
int p,n;
int sign[4000];
int flow[4000];
int path[4000][3];
struct Edge
{
    int s,t,c,next;
}edge[8000];
int head[4000];
int comps,compt,tot;
int minn(int a,int b)
{
    return a<b?a:b;
}
void init()
{
    memset(comp,0,sizeof(comp));
    comps=compt=0;
    for(int i=1;i<=n;i++)
    {
        int ok=0;
        scanf("%d",&comp[i].num);
        for(int j=0;j<p;j++)
        {
            scanf("%d",&comp[i].need[j]);
            if(comp[i].need[j]!=1)
                ok++;
        }
        if(ok==p)
            s[comps++]=i;
        ok=0;
        for(int j=0;j<p;j++)
        {
            scanf("%d",&comp[i].give[j]);
            if(comp[i].give[j]==1)
                ok++;
        }
        if(ok==p)
            t[compt++]=i;
    }
    int ent=0;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++)
    {
        int ok1=1;
        for(int k=0;k<p;k++)
        {
            if(comp[i].give[k]==0)
            {
                ok1=0;break;
            }
        }
        if(ok1)continue;
        for(int j=1;j<=n;j++)
        {
            int ok2=1;
            for(int k=0;k<p;k++)
            {
                if(comp[j].need[k]==1)
                {
                    ok2=0;break;
                }
            }
            if(ok2)continue;
            int ok=1;
            for(int k=0;k<p;k++)
            {
                if(comp[i].give[k]==0)
                {
                    if(comp[j].need[k]==1)
                    {
                        ok=0;
                        break;
                    }
                }
                if(comp[i].give[k]==1)
                {
                    if(comp[j].need[k]==0)
                    {
                        ok=0;break;
                    }
                }
            }
            if(ok)
            {
                edge[ent].s=i;edge[ent].t=j;edge[ent].c=minn(comp[i].num,comp[j].num);flow[ent]=edge[ent].c;edge[ent].next=head[i];head[i]=ent++;
                edge[ent].s=j;edge[ent].t=i;edge[ent].c=0;flow[ent]=0;edge[ent].next=head[j];head[j]=ent++;
            }
        }
    }
    for(int i=0;i<comps;i++)
    {
        edge[ent].s=0;edge[ent].t=s[i];edge[ent].c=comp[s[i]].num;flow[ent]=edge[ent].c;edge[ent].next=head[0];head[0]=ent++;
        edge[ent].s=s[i];edge[ent].t=0;edge[ent].c=0;flow[ent]=0;edge[ent].next=head[s[i]];head[s[i]]=ent++;
    }
    for(int j=0;j<compt;j++)
    {
        edge[ent].s=t[j];edge[ent].t=n+1;edge[ent].c=comp[t[j]].num;flow[ent]=edge[ent].c;edge[ent].next=head[t[j]];head[t[j]]=ent++;
        edge[ent].s=n+1;edge[ent].t=t[j];edge[ent].c=0;flow[ent]=0;edge[ent].next=head[n+1];head[n+1]=ent++;
    }
}
bool bfs(int start,int end)
{
    memset(pre,-1,sizeof(pre));
    pre[start]=0;
    queue<int>q;
    q.push(start);
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
        for(int i=head[temp];i!=-1;i=edge[i].next)
        {
            int temp2=edge[i].t;
            if(pre[temp2]==-1&&edge[i].c)
            {
                pre[temp2]=pre[temp]+1;
                q.push(temp2);
            }
        }
    }
    return pre[end]!=-1;
}
int dfs(int start,int end,int Min)
{
    if(start==end) return Min;
    int flow=0;
    for(int i=head[start];i!=-1;i=edge[i].next)
    {
        int temp=edge[i].t;
        if(pre[temp]==pre[start]+1&&edge[i].c)
        {
            int small=minn(Min-flow,edge[i].c);
            small=dfs(temp,end,small);
            if(small!=0)
            flow+=small;
            edge[i].c-=small;
            edge[i^1].c+=small;
        }
    }
    return flow;
}
void dinic()
{
    tot=0;sum=0;
    int flows=0,i=0;
    while(bfs(0,n+1))
        flows+=dfs(0,n+1,INT_MAX);
    printf("%d ",flows);
    for(int i=1;i<=n;i++)
    {
        for(int j=head[i];j!=-1;j=edge[j].next)
        {
            if(edge[j].t==0||edge[j].t==n+1)continue;
            if(edge[j].c!=0&&flow[j]==0)
            {
                path[tot][0]=edge[j].t;path[tot][1]=i;path[tot][2]=edge[j].c;
                tot++;
            }
        }
    }
    printf("%d\n",tot);
    for(int i=0;i<tot;i++)
    {
        printf("%d %d %d\n",path[i][0],path[i][1],path[i][2]);
    }
}
int main()
{
    while(~scanf("%d%d",&p,&n))
    {
        init();
        dinic();
    }
    return 0;
}

 

poj 3436 网络最大流加打印路径

标签:

原文地址:http://www.cnblogs.com/lthb/p/4417139.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!