http://poj.org/problem?id=3436
网络流 最重要的是要建图呀
由于速度的限制 要进行拆点 然后求解就可以了
需要注意的地方
1,和原点相连的点 满足进入它的各零件要求是0或2
2,和终点相连的点 需要用拆点后的后一个点连接
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include <iomanip>
using namespace std;
#define LL long long
#define sint short int
const int INF=0x3f3f3f3f;
//priority_queue<int,vector<int>,greater<int> >qt;
const int N=115;
int flow[N][N];
int cut[N][N];
struct node
{
int f;
int in[20];
int out[20];
}mem[N];
int L[N];
int S,E;
int p,n;
typedef pair<int,int>to;
vector<to>vt;
bool To(int i,int j)
{
for(int l=0;l<p;++l)
if(mem[j].in[l]==2||(mem[j].in[l]==mem[i].out[l]))
continue;
else
return false;
return true;
}
bool bfs()
{
queue<int>qt;
memset(L,-1,sizeof(L));
qt.push(S);
L[S]=0;
while(!qt.empty())
{
int x=qt.front();qt.pop();
for(int i=0;i<=E;++i)
if(L[i]==-1&&(flow[x][i]-cut[x][i])>0)
{L[i]=L[x]+1;qt.push(i);}
}
if(L[E]==-1)
return false;
return true;
}
int dfs(int x,int sum)
{
if(x==E)
return sum;
int tmp=sum;
for(int i=0;i<=E;++i)
{
if(L[x]+1==L[i]&&flow[x][i]-cut[x][i]>0)
{
int w=dfs(i,min(tmp,flow[x][i]-cut[x][i]));
cut[x][i]+=w;
cut[i][x]-=w;
tmp-=w;
}
if(tmp==0)
break;
}
return (sum-tmp);
}
int main()
{
//freopen("data.in","r",stdin);
while(cin>>p>>n)
{
S=2*n;
E=2*n+1;
memset(flow,0,sizeof(flow));
memset(cut,0,sizeof(cut));
for(int i=0;i<n;++i)
{
cin>>mem[i].f;
bool flag=true;
for(int j=0;j<p;++j)
{
cin>>mem[i].in[j];
if(mem[i].in[j]==1)
flag=false;
}
if(flag)
flow[S][i]=INF;
flag=true;
for(int j=0;j<p;++j)
{
cin>>mem[i].out[j];
if(!mem[i].out[j])
flag=false;
}
if(flag)
flow[i+n][E]=INF;
flow[i][i+n]=mem[i].f;
for(int l=0;l<i;++l)
{
if(To(l,i))
flow[l+n][i]=INF;
if(To(i,l))
flow[i+n][l]=INF;
}
}
int ans=0;
while(bfs())
{
int tmp;
while((tmp=dfs(S,INF)))
ans+=tmp;
}
vt.clear();
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
if(i!=j&&cut[i+n][j])
vt.push_back(to(i,j));
cout<<ans<<" "<<vt.size()<<endl;
for(unsigned int i=0;i<vt.size();++i)
{
int l=vt[i].first;
int r=vt[i].second;
cout<<(l+1)<<" "<<(r+1)<<" "<<cut[l+n][r]<<endl;
}
}
return 0;
}