有n个家庭,m个房间,一个房间只能两个家庭住。求最大匹配。
比较标准的二分图问题。先初始化把可能的家庭建边,然后跑一边匈牙利算法。
最后的答案是最大匹配数/2,因为建图时有重复。
#include <cstdio> #include <algorithm> #include <cstring> #include <map> using namespace std; const int MAXN = 410; int uN,vN; int g[MAXN][MAXN]; int linker[MAXN]; bool used[MAXN]; int dfs(int u) { for(int v=1;v<=vN;v++) if(g[u][v] && !used[v]) { used[v] = true; if(linker[v] == -1 || dfs(linker[v])) { linker[v] = u; return true; } } return false; } int Hungarian() { int res = 0; memset(linker,-1,sizeof linker); for(int u=1;u<=uN;u++) { memset(used,false,sizeof used); if(dfs(u)) res++; } return res; } int T,n,m; int R[500]; map<int,int> B; int main() { scanf("%d",&T); while(T--) { B.clear(); memset(g,0,sizeof g); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&R[i]); } for(int i=0;i<m;i++) { int tmp=0; scanf("%d",&tmp); B[tmp] = 1; } uN = n;vN = n; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i == j) continue; if(B[R[i]+R[j]] == 1) { g[i][j]=g[j][i]=1; } } } printf("%d ",Hungarian()/2); } }