写了POJ3281...那个题是求最大流的,我直接用它来验证一下最大流求得对不对。。。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<queue> #include<mylib.h> #define CLR(arr, val) memset(arr,val,sizeof(arr)) using namespace std; const int MAX=200,INF=100000000; class MinCostMaxFlow { public: int cost[MAX][MAX], flow[MAX][MAX], cap[MAX][MAX]; int GetMinCostMaxFlow(int s,int t,int v) { int max_flow=0; while(1) { SPFA(s, v); if(pre[t]==-1) break; int cur=t,minc=INF; do { if(minc>cap[pre[cur]][cur]-flow[pre[cur]][cur]) minc=cap[pre[cur]][cur]-flow[pre[cur]][cur]; }while((cur=pre[cur])!=s); max_flow+=minc; cur=t; do { flow[pre[cur]][cur]+=minc; flow[cur][pre[cur]]-=minc; }while((cur=pre[cur])!=s); } return max_flow; } private: int len[MAX],pre[MAX]; void SPFA(int s,int v) { fill(len,len+v,INF); CLR(pre,-1); len[s]=0; queue<int> q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=0;i!=v;i++) if(cap[u][i]-flow[u][i] > 0 && len[u]+cost[u][i] < len[i]) { pre[i]=u; len[i] = len[u]+cost[u][i]; q.push(i); } } } }; MinCostMaxFlow g; int main() { freopen("in.txt","r",stdin); int N,F,D,f,d,n; scanf("%d%d%d",&N,&F,&D); int s=2*N+F+D,t=s+1; fill((int*)g.cost,(int*)g.cost+s+2,1); for(int i=0;i!=N;i++) g.cap[i][i+N]=1; for(int i=0;i!=F;i++) g.cap[s][i+2*N]=1; for(int i=0;i!=D;i++) g.cap[i+2*N+F][t]=1; for(int i=0;i!=N;i++) { scanf("%d%d",&f,&d); for(int j=0;j!=f;j++) { scanf("%d",&n); g.cap[2*N+n-1][i]=1; } for(int j=0;j!=d;j++) { scanf("%d",&n); g.cap[i+N][2*N+n+F-1]=1; } } cout<<g.GetMinCostMaxFlow(s,t,s+2)<<endl; } 忽然发现上面的写法似乎有些问题,因为反向的费用应该设置成-1,不然退流时费用无法回退。 暂时重写中,准备A了POJ2135...得写成邻接表了。。