二分匹配模板
来源:互联网 发布:软件系统可靠性指标 编辑:程序博客网 时间:2024/05/17 18:15
#include <cstdio>#include <deque>#include <set>#include <string>#include <map>#include <vector>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>#include <queue>using namespace std;typedef long long LL;/* **************************************************************************//二分图匹配(匈牙利算法的DFS实现)//初始化:g[][]两边顶点的划分情况//建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配//g没有边相连则初始化为0//uN是匹配左边的顶点数,vN是匹配右边的顶点数//调用:res=hungary();输出最大匹配数//优点:适用于稠密图,DFS找增广路,实现简洁易于理解//时间复杂度:O(VE)//***************************************************************************///顶点编号从0开始的const int MAXN=510;int uN,vN;//u,v数目int g[MAXN][MAXN];int linker[MAXN];bool used[MAXN];bool dfs(int u)//从左边开始找增广路径{ int v; for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改if(g[u][v]&&!used[v]){ used[v]=true; if(linker[v]==-1 || dfs(linker[v])) {//找增广路,反向 linker[v]=u; return true; }} return false;//这个不要忘了,经常忘记这句}int hungary(){ int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=0;u<uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res;}struct node{int h;char sex[4];char style[105];char sport[105];}e[MAXN];int main(){int T;scanf("%d",&T);while(T --){int n;scanf("%d",&n);uN = vN = n;for(int i=0;i<n;i++){cin >> e[i].h >> e[i].sex >> e[i].style >> e[i].sport;}memset(g,0,sizeof(g));for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){if(i == j)continue;if(abs(e[i].h-e[j].h)>40 \|| strcmp(e[i].sex,e[j].sex) == 0 \|| strcmp(e[i].style,e[j].style) != 0 \|| strcmp(e[i].sport,e[j].sport) == 0){;}else{g[i][j] = 1;g[j][i] = 1;} }}int ans = hungary();printf("%d\n",uN-ans/2);}return 0;}