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; }