http://imlazy.ycool.com/post.2059102.html 看了这篇文章才做出来的,收获很大,膜拜神牛! 网络流的难点在于图的构建以及图的简化 //网络流——最大流 //此题的关键是构图和对图的简化以及流量的合并 //可参见http://imlazy.ycool.com/post.2059102.html //有非常详细的讲解 #include<iostream> #include<queue> #include<cstring> #define INF 2000000000 using namespace std; int cap[105][105],flow[105][105]; int rflow[105],pre[105]; int m,n,x,y,u,v,c,maxflow,st,ed,e; int pign[1005]; int connect[1005]; bool vis[1005]; int main() { //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); memset(cap,0,sizeof(cap)); memset(flow,0,sizeof(flow)); memset(vis,0,sizeof(vis)); memset(connect,0,sizeof(connect)); st = m + 1; ed = m + 2; for(int i = 1;i <= n;++i) { scanf("%d",&pign[i]); } for(x = 1;x <= m;++x)//构图十分重要 { scanf("%d",&e); while(e--) { scanf("%d",&y); if(!vis[y]) { cap[st][x] += pign[y];//合并流量 vis[y] = 1; connect[y] = x; } else { cap[connect[y]][x] = INF; } } scanf("%d",&c); cap[x][ed] = c; } for(;;)//最大流模板 { queue<int> q; memset(rflow,0,sizeof(rflow)); memset(pre,0,sizeof(pre)); rflow[st] = INF; q.push(st); while(!q.empty()) { u = q.front(); q.pop(); for(int v = 0;v <= ed;++v) { if(!rflow[v] && cap[u][v] > flow[u][v]) { pre[v] = u; rflow[v] = min(rflow[u],cap[u][v] - flow[u][v]); q.push(v); } } } if(rflow[ed] == 0) break; for(u = ed;u != st;u = pre[u]) { flow[pre[u]][u] += rflow[ed]; flow[u][pre[u]] -= rflow[ed]; } maxflow += rflow[ed]; } printf("%d/n",maxflow); return 0; }