二分匹配模板

来源:互联网 发布:软件系统可靠性指标 编辑:程序博客网 时间: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;}


原创粉丝点击