ACM Computer Factory POJ - 3436 网络流拆点+路径还原

每台电脑有p个组成部分,有n个工厂加工电脑。

每个工厂对于进入工厂的半成品的每个组成部分都有要求,由p个数字描述,0代表这个部分不能有,1代表这个部分必须有,2代表这个部分的有无无所谓。

每个工厂的产出也不尽相同,也是由p个数字代表,0代表这个部分不存在,1代表这个部分存在。每个工厂都有一个最大加工量。

给出这n个工厂的数据,求出最多能加工出多少台电脑

对于容量有限制,因此拆点

开始的机器没有零件,连接符合要求的点

最终的机器应该是完整的,把符合要求的点连接到汇点

因为已经拆过点限制了流量,所以其余容量记为INF就行了,

关于路径还原 在链式前向星保存边的时候同时记录边的起点,最后反向弧非零的边就是答案

#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <iostream>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define	per(ii,a,b) for(int ii=a;ii>=b;ii--)
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(a,b) cout<<#a<<‘[‘<<b<<"]="<<b[a]<<endl
using namespace std;
const int maxn=123+10;
const int maxm=1234+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
struct node {int pre,to,cap,next;}e[maxm];
int ss,tt,head[maxn],nume,dis[maxn];
inline void addx(int a,int b,int c){
	e[++nume]=(node){a,b,c,head[a]};
	head[a]=nume;
}
inline void add(int a,int b,int c){
	addx(a,b,c);addx(b,a,0);
}
bool bfs(int s=ss,int t=tt){
	int top=0,end=1;
	int q[maxn];
	q[0]=s;
//	for(int i=0;i<=t;i++) dis[i]=0;
	memset(dis,0,sizeof dis);
	dis[s]=1;
	while(top!=end){
		int now=q[top++];top%=maxn;
		for(int i=head[now];i;i=e[i].next){
			int to=e[i].to;
			if(!dis[to]&&e[i].cap){
				dis[to]=dis[now]+1;
				if(to==t)break;
				q[end++]=to;end%=maxn;
			}
		}
	}
	return dis[t];
}
int dfs(int now=ss,int last=INF){
	if(now==tt)return last;
	int flow=0,det;
	for(int i=head[now];i;i=e[i].next){
		int to=e[i].to;
		if(e[i].cap&&dis[to]==dis[now]+1){
			det=dfs(to,min(last-flow,e[i].cap));
			flow+=det;
			e[i].cap-=det;
			e[i^1].cap+=det;
			if(flow==last) return last;
		}
	}
	dis[now]=-1;
	return flow;
}
int p;
int cost[123];
int in[123][12];
int out[123][12];
int a[123];
int main(){
//#define test
#ifdef test
	freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
	nume=1;
	IO;
	cin>>p>>n;
	ss=0,tt=2*n+1;
	nume=1;
	rep(i,1,n){
	  cin>>cost[i];
	  int cnt=0;
    rep(j,1,p){
      cin>>in[i][j];
      if(in[i][j]!=1) cnt++;
    }
    if(cnt==p) add(ss,i,INF);
    cnt=0;
    rep(j,1,p){
      cin>>out[i][j];
      if(out[i][j]==1) cnt++;
    }
    if(cnt==p) add(i+n,tt,INF);
    add(i,i+n,cost[i]);
	}
  rep(i,1,n){
    rep(j,1,n){
      if(i==j) continue;
      int cnt=0;
      rep(k,1,p){
        if(in[j][k]!=2&&in[j][k]!=out[i][k]){
          cnt++;
          break;
        }
      }
      if(cnt==0) add(i+n,j,INF);
    }
  }
  int ans=0;
  while(bfs()) ans+=dfs();
  if(ans==0) cout<<"0 0\n";
  else {
    int cnt=0;
    for(int i=2;i<=nume;i+=2){
      if(abs(e[i].pre-e[i].to)!=n&&e[i].to>ss&&e[i].pre>ss&&e[i].pre<tt&&e[i].to<tt&&e[i^1].cap!=0){
        a[cnt++]=i;
      }
    }
    cout<<ans<<‘ ‘<<cnt<<‘\n‘;
    rep(i,0,cnt-1){
      cout<<e[a[i]].pre-n<<‘ ‘<<e[a[i]].to<<‘ ‘<<e[a[i]^1].cap<<‘\n‘;
    }
  }
#ifdef test
	fclose(stdin);fclose(stdout);system("out.txt");
#endif
	return 0;
}

  

原文地址:https://www.cnblogs.com/nervendnig/p/9084865.html

时间: 2024-08-24 09:03:05

ACM Computer Factory POJ - 3436 网络流拆点+路径还原的相关文章

A - ACM Computer Factory - poj 3436(最大流)

题意:有一个ACM工厂会生产一些电脑,在这个工厂里面有一些生产线,分别生产不同的零件,不过他们生产的电脑可能是一体机,所以只能一些零件加工后别的生产线才可以继续加工,比如产品A在生产线1号加工后继续前往生产线2号继续加工,直到成为完全产品.输入 P 意思是这个电脑需要P个零件,N表示有N个生产线,每个生产线都有最大加工量,并且需要什么零件和输出的是什么零件,0表示没有这个零件,1表示有这个零件,2表示有没有都可以. 样例说明: 3 4 1号: 15 0 0 0 --> 0 1 0 2号: 10

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

POJ 3436 ACM Computer Factory(网络最大流)

http://poj.org/problem?id=3436 ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5286   Accepted: 1813   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the particip

Poj 3436 ACM Computer Factory (最大流)

题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题思路: 因为需要输出流水线要经过的工厂路径,如果要用电脑状态当做节点的话,就GG了.所以建图的时候要把工厂当做节点.对于节点i,能生产si电脑的节点可以进入节点i,能转化ei电脑的节点可以由i节点进入.要注意对于每一个节点要进行拆点,防止流量发生错误. 1 #include <queue> 2 #

POJ 3436 ACM Computer Factory (最大流 + 输出路径)

POJ 3436 ACM Computer Factory 链接:http://poj.org/problem?id=3436 题意:每台电脑有P部分,可以通过不同的机器来进行加工.有N台机器,每台机器用2 P +1 个整数来描述:Qi  Si,1  Si,2 ...  Si,p  Di,1  Di,2. ..  Di,p,其中Qi 指定了机器的性能,表示每小时加工的电脑数量.Si,j 为第j 部分的输入规格,0表示该部分不能被加工过,1表示该部分必须被加工过,2表示都可以.Di,k 为第k 部

18.11.23 POJ 3436 ACM Computer Factory(dinic)

描述 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 the

POJ-3436 ACM Computer Factory(网络流EK)

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

POJ3436:ACM Computer Factory(最大流)

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9963   Accepted: 3738   Special Judge 题目链接:http://poj.org/problem?id=3436 Description: As you know, all the computers used for ACM contests must be identical, so the pa

poj 3436 网络流构图经典

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6012   Accepted: 2083   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. Th