ACM Computer Factory--POJ 3436
1、题目类型:图论、最大流、Edmonds_Karp算法。
2、解题思路:(1)根据输入构建G[][]矩阵,注意machine的各part进入和输出状态,必须Judge成功才允许存在边的连通;(2)添加源点和结点,源点与所有输入part状态全为0的machine相连,结点与所有输入part状态全为1的machine相连;(3)运用Edmonds_Karp算法求解最大流。
3、注意事项:G[][]的建立,权值在节点上。
4、实现方法:
#include<iostream>
#include<queue>
#define inf 99999999
using namespace std;
struct Node
{
int w;
int in[12];
int out[12];
};
Node Matchin[110];
int P,N,S,T,Max_Flow;
int G[120][120],G2[120][120];
int tmp[240],pre[240];
bool Judge(int *s1,int *s2,int n)
{
int i;
for(i=0;i<n;i++)
{
if(s1[i]!=s2[i] && s1[i]!=2 && s2[i]!=2)
return false;
}
return true;
}
void Init()
{
int i,j;
S=0;
T=2*N+1;
Max_Flow=0;
memset(G,0,sizeof(G));
for(i=1;i<=N;i++)
{
cin>>Matchin[i].w;
for(j=0;j<P;j++)
cin>>Matchin[i].in[j];
for(j=0;j<P;j++)
cin>>Matchin[i].out[j];
G[i][i+N]=Matchin[i].w;
}
for(i=1;i<=N;i++)
{
for(j=i+1;j<=N;j++)
{
if(Judge(Matchin[i].out,Matchin[j].in,P))
G[i+N][j]=inf;
if(Judge(Matchin[j].out,Matchin[i].in,P))
G[j+N][i]=inf;
}
G[S][i]=inf;
for(j=0;j<P;j++)
{
if(Matchin[i].in[j]==1)
{
G[S][i]=0;
break;
}
}
G[i+N][T]=inf;
for(j=0;j<P;j++)
{
if(Matchin[i].out[j]==0||Matchin[i].out[j]==2)
{
G[i+N][T]=0;
break;
}
}
}
}
void Print()
{
int i,j;
int edge=0;
for(i=N+1;i<T;i++)
{
for(j=1;j<=N;j++)
{
if(G[i][j]<G2[i][j])
edge++;
}
}
cout<<Max_Flow<<' '<<edge<<endl;
for(i=N+1;i<T;i++)
{
for(j=1;j<=N;j++)
{
if(G[i][j]<G2[i][j])
{
cout<<i-N<<' '<<j<<' '<<G2[i][j]-G[i][j]<<endl;
}
}
}
}
bool BFS()
{
queue<int> Q;
memset(pre,0xff,sizeof(pre));
memset(tmp,0,sizeof(tmp));
Q.push(S);
tmp[S]=inf;
while(!Q.empty())
{
int v=Q.front();
Q.pop();
for(int i=S;i<=T;i++)
{
if(G[v][i]>0&&pre[i]==-1)
{
tmp[i]=tmp[v]>G[v][i]?G[v][i]:tmp[v];
Q.push(i);
pre[i]=v;
if(i==T)
return true;
}
}
}
return false;
}
void E_K()
{
while(BFS())
{
Max_Flow+=tmp[T];
for(int i=T;i!=S;i=pre[i])
{
G[pre[i]][i]-=tmp[T];
G[i][pre[i]]+=tmp[T];
}
}
}
int main()
{
cin>>P>>N;
Init();
memcpy(G2,G,sizeof(G));
E_K();
Print();
return 0;
}