匈牙利算法

来源:互联网 发布:3d签到墙源码 编辑:程序博客网 时间:2024/05/20 18:49

匈牙利算法:

月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。

现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。

现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。

假设男孩们分别编号为1~n,女孩们也分别编号为1~n

输入

第一行是一个整数T,表示测试数据的组数(1<=T<=400)
每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n(n<=500,K<=10 000)
随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n)

输出

对每组测试数据,输出最多可能促成的幸福家庭数量

样例输入

1

3 4

1 1

1 3

2 2

3 2

样例输出

2

 

#include <cstdio>#include <vector>#include <cstring>using namespace std;vector<int>map[505];bool vis[505];int conn[505];bool dfs(int x){   for(int i=0;i<map[x].size();i++)    {       int y=map[x][i];       if(!vis[y])       {           vis[y]=true;           if(conn[y]==0||dfs(conn[y]))  //y还没结婚或者y已经结婚但是她的配偶还可以找其他人结婚;           {                conn[y]=x;   y和x结婚了;                return  true;           }       }    }   return false;}int main(){   int ncase;   scanf("%d",&ncase);   while(ncase--)    {       int n,k;       memset(conn,0,sizeof(conn));       memset(map,0,sizeof(map));       scanf("%d %d",&n,&k);       for(int i=0;i<k;i++)       {            int a,b;           scanf("%d %d",&a,&b);           map[a].push_back(b);  转换成://map[1]= { 1 , 3 };  map[2]={ 2 }; map[3]={  2 };       }       int ans=0;       for(int i=1;i<=n;i++)       {           memset(vis,false,sizeof(vis));           if(dfs(i))           ans++;       }       printf("%d\n",ans);    }   return 0;}

0 0