UVA - 11082 Matrix Decompressing (最大流,技巧)
2015-08-26 11:50
776 查看
很经典的网络流模型,行编号和列编号分别看成一个点,行和列和分别看出容量,一个点(x,y)看出是一条边,边的容量下界是1,所以先减去1,之后在加上就好了。
建图的时候注意分配好编号,解从残留网络中的边找。
前向星建图的话,打印解会比较麻烦。
建图的时候注意分配好编号,解从残留网络中的边找。
前向星建图的话,打印解会比较麻烦。
#include<bits/stdc++.h> using namespace std; const int maxn = 42; struct Edge { int v,cap,flow; }; vector<Edge> edges; #define PB push_back vector<int> G[maxn]; void AddEdge(int u,int v,int c) { G[u].PB(edges.size()); edges.PB(Edge{v,c,0}); G[v].PB(edges.size()); edges.PB(Edge{u,0,0}); } const int INF = 0x3f3f3f3f; int S,T; int vcnt; bool vis[maxn]; int d[maxn]; int q[maxn<<1]; bool bfs() { memset(vis,0,sizeof(bool)*vcnt); int l = 0,r = 0; q[r++] = S; vis[S] = true; while(r>l){ int u = q[l++]; for(int i = 0; i < G[u].size(); i++){ Edge &e = edges[G[u][i]]; if(!vis[e.v] && e.cap >e.flow){ vis[e.v] = true; d[e.v] = d[u]+1; q[r++] = e.v; } } } return vis[T]; } int cur[maxn]; int dfs(int u,int a) { if(u == T||!a) return a; int flow = 0, f; for(int &i = cur[u]; i < G[u].size(); i++){ Edge &e = edges[G[u][i]]; if(d[e.v] == d[u]+1 && (f = dfs(e.v,min(a,e.cap-e.flow)))>0){ e.flow += f; edges[G[u][i]^1].flow -= f; flow += f; a -= f; if(!a) break; } } return flow; } int MaxFlow() { int flow = 0; while(bfs()){ memset(cur,0,sizeof(int)*vcnt); flow += dfs(S,INF); } return flow; } const int N = 20; int rid ,cid ; void init() { vcnt = 2; edges.clear(); } int main() { //freopen("in.txt","r",stdin); S = 0; T = 1; int testCase; scanf("%d",&testCase); int mcnt = 0; while(testCase--){ init(); int R,C,cap,pre; scanf("%d%d",&R,&C); for(int i = 0, M = R+C+2; i < M; i++) G[i].clear(); pre = 0; for(int i = 0; i < R; i++) { rid[i] = vcnt++; scanf("%d",&cap); AddEdge(S,rid[i],cap-pre-C); pre = cap; } pre = 0; for(int i = 0; i < C; i++){ cid[i] = vcnt++; scanf("%d",&cap); AddEdge(cid[i],T,cap-pre-R); pre = cap; } for(int i = 0; i < R; i++) for(int j = 0; j < C; j++){ AddEdge(rid[i],cid[j],19); } MaxFlow(); printf("Matrix %d\n",++mcnt); for(int i = 0; i < R; i++){ int k = 0, u = rid[i]; for(int j = 0; j < G[u].size(); j++){ Edge &e = edges[G[u][j]]; if(e.v == cid[k]){ printf("%d%c",e.flow+1,++k==C?'\n':' '); if(k == C) break; } } } if(testCase) putchar('\n'); } return 0; }
相关文章推荐
- Mongodb 之insert瞬时完成,测试数据---飞天博客
- 元素定位之上传文件
- Python验证Url地址的正则表达式
- Cacti详细安装步骤
- Android 再按一次返回键退出的第三种方式
- textview 删除线
- JavaScript调试
- JavaScript事件处理
- C++_编写动态链接库
- 深入理解C语言的函数调用过程
- Java这点事
- jsoncpp的api简要说明
- Python os.walk
- iphone开发之UIButton按钮的使用(三)拖线实现 center和bounds实现控制组件的大小和位置
- JavaScript概述
- JavaScript的对话框
- 直接push jar包到system/framework,供APK调用此jar包中的类
- Android SDK Tools Platform-tools Build-tools
- dup和dup2的用法区别
- jquery json string 转换 合并