题目:POJ 1636
题目大意:两个监狱交换等数量的犯人(不超过一半),有的犯人不能在一个监狱,求最大交换人数
题解:用并查集求出有关系的人数,以数对的形式表示,然后转化为背包问题,用动态规划求解
AC代码:
#include<iostream>
#include<string.h>
using namespace std;
#define MAX 410
int cnt1[MAX];
int cnt2[MAX];
int f[MAX];
int dp[MAX / 2][MAX / 2];
int m, r;
int cnt; //记录连通集个数
struct P
{
int a;
int b;
}p[MAX];
//并查集,记录每个连通集两个监狱中有关系的人数
void init() {
memset(cnt1, 0, sizeof(cnt1));
memset(cnt2, 0, sizeof(cnt2));
memset(dp, 0, sizeof(dp));
cnt = 0;
for (int i = 0; i < MAX; i++)
f[i] = i;
}
int find(int a) {
return a == f[a] ? a : f[a] = find(f[a]);
}
void merge(int a, int b) {
int fa = find(a);
int fb = find(b);
if (fa != fb)f[fa] = fb;
}
int main() {
int n;
int a, b; //记录有关系的犯人
cin &