题意:A国家有M个代表,B国有N个代表,其中有K对代表可以进行谈判(一个是A国的,一个是B国的),并且每一个代表至少被包含在其中一对中(也就是说,每个人可以至少找到另外一个人谈判),每一对谈判需要一对电话联系(一对电话联系数目算1),现在使每个人都能进行电话联系的最少联系数目
思路:既然是求最少的联系数目,也就是找最少的对数。可以先找到最大二分匹配(此时的匹配全都不重复,都是一对一的),然后加上剩下未匹配的人得数目即可(因为每个人肯定至少找到另外一个人进行谈判)
n:A国代表人数
m:B国代表人数
最大二分匹配的人数=ans
未匹配的人数=n+m-2*ans
覆盖所有点的最少边数 = 最大二分匹配的人数+未匹配的人数(还未与心目中的点匹配,心目中的点已经跟其他人匹配所以只能等待)=ans+n+m-2*ans=n+m-ans
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include<iomanip>
#include <queue>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define int long long
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 1100;
const double PI = acos(-1);
int a[N][N]; //存储关系的
int st[N]; //每次dfs判断的数组
int match[N];//女生数组
int n,m,k;
int dfs(int x)
{
for(int i=1;i<=m;i++)
{
if(a[x][i]==1 && st[i]==0 )
{
st[i] = 1; //x抢先一步预定
if(match[i]==0 || dfs(match[i]))
{
match[i] = x;
return 1;
}
}
}
return 0;
}
void solve()
{
memset(match,0,sizeof(match)); //女生数组匹配关系
memset(a,0,sizeof(a)); //关系数组
int sum=0;
cin>>n>>m>>k;
int x,y;
for(int i=1;i<=k;i++)
{
cin>>x>>y;
a[x][y]=1;
}
for(int i=1;i<=n;i++)
{
memset(st,0,sizeof(st));
if(dfs(i)==1) sum++;
}
cout<<n+m-ans<<endl;
}
signed main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T = 1;
while(T--)
solve();
}