题解:POJ1636 Prison rearrangement 【DP】

传送门

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
using namespace std;
#define re register
#define gc getchar()
#define ll long long
inline int read() {
	re int x(0),f(1);re char ch(gc);
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=gc;}
	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gc;
	return x*f ;
}
const int N=410;
int T,m,r,vis[N],w,b,tot,p[N],q[N],f[N][N];
vector<int> a[N];
void dfs(int u) {
	vis[u]=1;
	if(u<=m) w++;
	else b++;
	for(int i=0;i<a[u].size();++i) {
		int v=a[u][i];
		if(!vis[v]) dfs(v);
	}
}
int main() {
	
	freopen("y.txt","r",stdin);
	
	T=read();
	while(T--) {
		m=read(),r=read();
		for(int i=1;i<=m*2;++i)
			a[i].clear();
		memset(vis,0,sizeof(vis));
		memset(f,0,sizeof(f));
		for(int i=1;i<=r;++i) {
			int u=read(),v=read();
			a[u].push_back(v+m);
			a[v+m].push_back(u);
			tot=0;
		}
		for(int i=1;i<=m*2;++i) 
			if(!vis[i]) {
				b=w=0,dfs(i);
				p[++tot]=w,q[tot]=b;
			}
			f[0][0]=1;
			int M=0;
			for(int i=1;i<=tot;++i) {
				for(int j=m/2;j>=p[i];--j)
					for(int k=m/2;k>=q[i];--k)
						if(f[j-p[i]][k-q[i]])
							f[j][k]=1;
				M=max(M+p[i],m+q[i]);
			}
		int i;
		for(i=m/2;i>=0;--i) 
			if(f[i][i])
				break;
		cout<<i<<endl;
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43464026/article/details/88240959