UVA 11082 矩阵解压(网络流建模)
矩阵解压
紫书P374 建模真的是挺难的,如果直接给我这题,我是想不到用网络流的,所以还应多做网路流建模,学会如何转化成网络流
还有,现在用的EK算法是比较慢的,还应去看看Dnic和ISAP,并且理解和应用
【题目链接】矩阵解压
【题目类型】网络流建模
&题解:
我先是看了紫书,懂了他的思路,感觉不算难,就自己写了一下。写完之后,哎我去,那EK写的惨不忍睹啊,静无限循环了,→_→ 接着,就照的刘汝佳的代码码了一遍,样例都过不去。= = 又找了半天的bug,发现push的边push错了,改完终于a了。 心累
&代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=50+5;
const int INF=1000000000;
struct Edge{
int from,to,cap,flow;
};
struct EdmondsKarp{
vector<Edge> edges;
vector<int> G[maxn];
void Init(int n){
for(int i=0;i<n;i++)
G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,0,0});
int m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
int a[maxn];
int p[maxn];
int MaxFlow(int s,int t){
int flow=0;
for(;;){
memset(a,0,sizeof(a));
queue<int> Q;
Q.push(s);
a[s]=INF;
while(!Q.empty()){
int x=Q.front(); Q.pop();
for(int i=0;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if (!a[e.to]&&e.cap>e.flow){
p[e.to]=G[x][i];
a[e.to]=min(a[x],e.cap-e.flow);
Q.push(e.to);
}
}
if (a[t]) break;
}
if (!a[t]) break;
for(int u=t;u!=s;u=edges[p[u]].from){
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
}
flow+=a[t];
}
return flow;
}
};
EdmondsKarp g;
int no[maxn][maxn];
int main(){
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out","w",stdout);
#endif
int T,R,C,v,kase=1;
scanf("%d",&T);
for(;kase<=T;kase++){
scanf("%d%d",&R,&C);
g.Init(R+C+2);
int last=0;
for(int i=1;i<=R;i++){
scanf("%d",&v);
g.AddEdge(0,i,v-last-C);
last=v;
}
last=0;
for(int i=1;i<=C;i++){
scanf("%d",&v);
g.AddEdge(R+i,R+C+1,v-last-R);
last=v;
}
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++){
g.AddEdge(i,R+j,19);
no[i][j]=g.edges.size()-2;
}
int re=g.MaxFlow(0,R+C+1);
// DG(g.edges.size())
// for(int i=0;i<38;i++){
// DGG(g.edges[i].cap,g.edges[i].flow)
// }
printf("Matrix %d\n", kase);
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
printf("%d%c",g.edges[no[i][j]].flow+1,j==C?'\n':' ');
printf("\n");
}
}