HOJ 2634 网络流 【蕴含式最大获利问题】
2014-07-18 16:56
375 查看
参考:http://wenku.baidu.com/link?url=ZO8hOpUlTb04rmoob64R-OohRZfyw-xv7cMdwKX-_RXsUKnExnJSxlYuEnnRqF3bR8hIYJuKjrgiN38cIBXjtNi_7y-FRy7rZRc_vGP9Bj_
【蕴含式最大获利问题】
【蕴含式最大获利问题】
#include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int MAXN=210,inf=0x3f3f3f3f; struct ISAP { struct Edge { int from,to,cap,flow; Edge(){} Edge(int a,int b,int c,int d):from(a),to(b),cap(c),flow(d){} }; int n,m,s,t;//结点数,边数(含反向弧),源点,汇点 vector<Edge> edges;//边表,edges[e]&edges[e^1]互为反向弧 vector<int> G[MAXN];//邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[MAXN];//BFS使用 int d[MAXN];//从起点到i的距离 int cur[MAXN];//当前弧下标 int p[MAXN];//可增广路上的上一条弧 int num[MAXN];//距离标号计数 void AddEdge(int from,int to,int cap)//重边不影响 { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0));//容量为0,表示反向弧 m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } void init(int n) { this->n=n; for(int i=0;i<n;++i) G[i].clear(); edges.clear(); } void BFS()//反向 { memset(vis,0,sizeof(vis)); queue<int> Q; Q.push(t); d[t]=0; vis[t]=1; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); ++i) { Edge& e=edges[G[x][i]^1]; if(!vis[e.from]&&e.cap>e.flow) { vis[e.from]=1; d[e.from]=d[x]+1; Q.push(e.from); } } } } int Augment() { int x=t,a=inf; while(x!=s) { Edge& e=edges[p[x]]; a=min(a,e.cap-e.flow); x=edges[p[x]].from; } x=t; while(x!=s) { edges[p[x]].flow+=a; edges[p[x]^1].flow-=a; x=edges[p[x]].from; } return a; } int Maxflow(int s,int t)//结点数 { this->s=s,this->t=t; int flow=0; BFS(); memset(num,0,sizeof(num)); for(int i=0;i<n;++i) ++num[d[i]]; int x=s; memset(cur,0,sizeof(cur)); while(d[s]<n) { if(x==t) { flow+=Augment(); x=s; } int ok=0; for(int i=cur[x];i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(e.cap>e.flow&&d[x]==d[e.to]+1)//Advance { ok=1; p[e.to]=G[x][i]; cur[x]=i; x=e.to; break; } } if(!ok)//Retreat { int m=n-1; for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(e.cap>e.flow) m=min(m,d[e.to]); } if(--num[d[x]]==0) break;//gap优化 num[d[x]=m+1]++; cur[x]=0; if(x!=s) x=edges[p[x]].from; } } return flow; } void dfs1(int x) { vis[x]=1; for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(e.flow<e.cap&&!vis[e.to]) dfs1(e.to); } } void dfs2(int x) { vis[x]=1; for(int i=0;i<g[x].size();++i) if(!vis[g[x][i]]) dfs2(g[x][i]); } vector<int> g[MAXN]; void solve(int y) { for (int i=0;i<n;i++) g[i].clear(); for (int i=0;i<edges.size();i++) if (edges[i].flow<edges[i].cap) g[edges[i].to].push_back(edges[i].from); memset(vis,0,sizeof(vis)); dfs1(s); //dfs2(t); printf("project:\n"); for (int i=1;i<=y;i++) if (vis[i]) printf("%d ",i); printf("\nemployer:\n"); for (int i=y+1;i<n-1;i++) if (vis[i]) printf("%d ",i-y); } }it; int n,m; void doit() { scanf("%d%d",&n,&m); int t=n+m+1,tot=0; it.init(t+1); for (int i=1,x;i<=n;i++) { scanf("%d",&x); tot+=x; it.AddEdge(0,i,x); } for (int i=1,x;i<=m;i++) { scanf("%d",&x); it.AddEdge(n+i,t,x); } for (int i=1,x,y;i<=n;i++) { scanf("%d",&x); for (int j=1;j<=x;j++) { scanf("%d",&y); y++; it.AddEdge(i,n+y,inf); } } printf("%d\n",tot-it.Maxflow(0,t)); //it.solve(n); } int main() { int cas; scanf("%d",&cas); while (cas--) doit(); return 0; }
相关文章推荐
- hdu3879 网络流(经典最大获利问题)
- [ HOJ 2713]Matrix1[网络流] 最大点权独立集问题
- HOJ 2634 How to earn more [网络流]最大权闭合图
- HOJ 2713 Matrix1 [网络流] 最大点权独立集问题
- hdu3879 网络流(经典最大获利问题)
- 线性规划与网络流24题之分配问题 最大费用最大流、最小费用最大流、二分图的最佳匹配
- 线性规划与网络流24题之数字梯形问题 最大权不相交路径
- 网络流24题(06)最长递增子序列问题(最多不相交路径 + 最大流)
- 网络流24题(07)试题库问题(二分图多重匹配 + 最大流)
- 线性规划与网络流24题 2太空飞行计划问题 最大权闭合图问题(不懂) nefu 476
- 线性规划与网络流24题の17 运输问题(最小费用最大流、最大费用最大流)
- 线性规划与网络流24题之方格取数问题 二分图点权最大独立集
- 线性规划与网络流24题 2太空飞行计划问题 最大权闭合图问题(不懂) nefu 476
- 线性规划与网络流24题の1 飞行员配对方案问题(最大匹配)
- Geeks Ford-Fulkerson Algorithm for Maximum Flow Problem 最大网络流问题
- 线性规划与网络流24题の2 太空飞行计划问题(最大权闭合图问题)
- 线性规划与网络流24题之海底机器人问题 最大费用最大流
- 网络流24题(05)魔术球问题(最小路径覆盖 + 最大流)
- 网络流问题 最大流 ford-fulkerson算法 edmonds-karp算法
- 网络流24题(11)航空路线问题(最大费用最大流)