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
", 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?'
':' ');
		printf("
");
	}
}
原文地址:https://www.cnblogs.com/s1124yy/p/6048393.html