Matrix Decompressing UVA - 11082 (SAP模板)


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=100;

int v1[maxn],v2[maxn];

struct Edge{
	int from,to,cap,flow;
	Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){	}
};
/*
很好的题,感觉很形象,就像是交错的管道,只知道流入的流量
流出的流量,中间的交叉口就是两个点之间的流量
还有就是怎样来保证所有的树不为0,是直接把所有的数字
都减掉1,这样的话,就算有的边流量是0,也没有问题了 
*/

struct EK{
	int n,m;
	vector<Edge> edges;
	vector<int> G[maxn];
	
	void init(int n){
		for(int i=0;i<n;i++)G[i].clear();
		edges.clear();
	}
	
	void add_edge(int u,int v,int c){
		edges.push_back(Edge(u,v,c,0));
		edges.push_back(Edge(v,u,0,0));
		m=edges.size();
		G[u].push_back(m-2);
		G[v].push_back(m-1);
	}
	int a[maxn],p[maxn];
	int  Maxflow(int s,int t){
		int flow=0;
		for(;;){
			memset(a,0,sizeof(a));
			memset(p,0,sizeof(p));
			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++){
					int to=G[x][i];
					Edge& e=edges[to];
					if(!a[e.to]&&e.cap>e.flow){
						a[e.to]=min(a[x],e.cap-e.flow); 
						p[e.to]=G[x][i];
						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;
	} 
}ek;
int ans[maxn][maxn];
int main(){
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	for(int kase=1;kase<=T;kase++){
		int n,m;
		cin>>n>>m;
		ek.init(n+m+2);
		int st=0,ed=n+m+1;
		
		for(int i=1;i<=n;i++){
			cin>>v1[i];
			ek.add_edge(st,i,v1[i]-v1[i-1]-m);
		}
		for(int i=1;i<=m;i++){
			cin>>v2[i];
			ek.add_edge(n+i,ed,v2[i]-v2[i-1]-n);
		}

		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				ek.add_edge(i,n+j,19);
			}
		}
		
		int tmp= ek.Maxflow(st,ed);
		
		//
		//cout<<"tmp"<<tmp<<endl;
		
		for(int i=1;i<=n;i++){
			for(int j=0;j<ek.G[i].size();j++){
				Edge& e=ek.edges[ek.G[i][j]];
				if(e.to>n&&e.to<ed){
					ans[i][e.to-n]=e.flow+1;
				}
			}
		}
		
		if(kase>1)cout<<endl;
		cout<<"Matrix "<<kase<<endl;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(j==1) cout<<ans[i][j];
				else cout<<" "<<ans[i][j];
			}
			cout<<endl;
		}
	}	
	return 0;
}

 

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=100;
const int MAXM=410*2;

int v1[MAXN],v2[MAXN];

//SAP模板
//注意从1开始,不要去用0 
struct SAP {
	struct Edge {
		int from,to,next,cap,flow;
		Edge(int _from=0,int _to=0,int _cap=0,int _flow=0,int _next=0){
			from=_from,to=_to,next=_next,cap=_cap,flow=_flow;
		} 
	} edge[MAXM]; //注意是 MAXM
	int tol;
	int head[MAXN];
	int gap[MAXN],dep[MAXN],cur[MAXN];
	void init() {
		tol = 0;
		memset(head,-1,sizeof(head));
	}
	void addedge(int u,int v,int w,int rw = 0) {
		edge[tol]=Edge(u,v,w,0,head[u]);
		head[u] = tol++;
		edge[tol]=Edge(v,u,rw,0,head[v]);
		head[v] = tol++;
	}
	int Q[MAXN];
	void BFS(int start,int end) {
		memset(dep,-1,sizeof(dep));
		memset(gap,0,sizeof(gap));
		gap[0] = 1;
		int front = 0, rear = 0;
		dep[end] = 0;
		Q[rear++] = end;
		while(front != rear) {
			int u = Q[front++];
			for(int i = head[u]; i != -1; i = edge[i].next) {
				int v = edge[i].to;
				if(dep[v] != -1)continue;
				Q[rear++] = v;
				dep[v] = dep[u] + 1;
				gap[dep[v]]++;
			}
		}
	}

	int S[MAXN];
	int MaxFlow(int start,int end,int N) {//一共多少个点
		BFS(start,end);
		memcpy(cur,head,sizeof(head));
		int top = 0;
		int u = start;
		int ans = 0;
		while(dep[start] < N) {
			if(u == end) {
				int Min = INF;
				int inser;

				for(int i = 0; i < top; i++)
				if(Min > edge[S[i]].cap - edge[S[i]].flow) {
						Min = edge[S[i]].cap - edge[S[i]].flow;
						inser = i;
				}
				for(int i = 0; i < top; i++) {
					edge[S[i]].flow += Min;
					edge[S[i]^1].flow -= Min;
				}
				ans += Min;
				top = inser;
				u = edge[S[top]^1].to;
				continue;
			}
			bool flag = false;
			int v;
			for(int i = cur[u]; i != -1; i = edge[i].next) {
				v = edge[i].to;
				if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) {
					flag = true;
					cur[u] = i;
					break;
				}
			}
			if(flag) {
				S[top++] = cur[u];
				u = v;
				continue;
			}
			int Min = N;
			for(int i = head[u]; i != -1; i = edge[i].next)
				if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) {
					Min = dep[edge[i].to];
					cur[u] = i;
				}
			gap[dep[u]]--;
			if(!gap[dep[u]])return ans;
			dep[u] = Min + 1;
			gap[dep[u]]++;
			if(u != start)u = edge[S[--top]^1].to;
		}
		return ans;
	}
}sap;

int ans[MAXN][MAXN];
int main(){
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	for(int kase=1;kase<=T;kase++){
		int n,m;
		cin>>n>>m;
		
		sap.init();
		int st=n+m+1,ed=n+m+2;
		
		for(int i=1;i<=n;i++){
			cin>>v1[i];
			sap.addedge(st,i,v1[i]-v1[i-1]-m);
		}
		for(int i=1;i<=m;i++){
			cin>>v2[i];
			sap.addedge(n+i,ed,v2[i]-v2[i-1]-n);
		}

		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				sap.addedge(i,n+j,19);
			}
		}
		
		int tmp= sap.MaxFlow(st,ed,n+m+2);
		
		memset(ans,0,sizeof(ans));
		for(int i=0;i<sap.tol;i++){
			if(!sap.edge[i].cap)continue;
			int u=sap.edge[i].from,v=sap.edge[i].to;
			ans[u][v-n]+=(sap.edge[i].flow);
		}
	
		if(kase>1)cout<<endl;
		cout<<"Matrix "<<kase<<endl;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(j==1) cout<<ans[i][j]+1;
				else cout<<" "<<ans[i][j]+1;
			}
			cout<<endl;
		}
	}	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值