Gym - 101915D Largest Group (二分图最大团)

探讨如何通过转换为二分图补图的最大匹配问题,利用匈牙利算法高效解决最大团问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                  D、 Largest Group

One day your university decided to run some statistics. They wanted to study friendship relations among boys and girls, and its effectiveness on their grades.

Strange thing about your university is that it has the exact same number of boys and girls. More formally, the university has P boys numbered from 1 to P, and P girls numbered from 1 to P.

We know that any pair of boys are surely friends, and any pair of girls are definitely friends. However, boys and girls are not always friends. To be precise, the university has a list of length N containing the friendship relations between girls and boys. the ith friendship relation is described by two integers bi and gimeaning that the boy number bi and girl number gi are friends.

One of the statistics your university is interested in, is the largest group of people (boys and girls) where any pair of them are friends. Can you write a program that would solve such a problem?

Input

The first line contains an integer T, the number of test cases.

Each test case starts with a line containing 2 space separated integers P and Ndenoting both the number of boys and girls at your university, and the number of friendship relations. (1 ≤ P ≤ 20), (0 ≤ N ≤ P2).

N lines follow. The ith line of them contains 2 space separated integers bi, gidescribing a friendship relation.

Output

For each test case print a single line, containing a single integer, denoting the number of people in the largest group where any pair of people among them are friends.

Example

Input

2
4 5
1 2
2 2
3 2
4 2
1 4
3 4
1 2
2 1
1 1
2 2

Output

5
4

 

一、原题地址

点我传送

 

二、大致题意

现在有P个男生和P个女生,他们之间存在n个关系,每对关系用 ai 和 bj 来表示第 i 个男生和第 j 个女生相识。

默认已知所有男生互相认识,所有女生也互相认识,现在要求找出一个团体,这个团体满足集合内所有的人都互相认识(也就是构成了完全图)。

求这个团体内集合元素的最大值。

 

三、思路

原本写了一大坨的爆搜程序三重的判断试图来跑出数据量只有40的答案,TLE了之后非常绝望。之后发现是一道结论题。这样寻找最大完全图的问题大家把这个叫做最大团。

二分图的最大团 = 它补图的最大独立集。

二分图最大团的定义是:一个最大的点的集合,该集合内的任意两点都有边相连。

二分图的最大独立集是:一个最大的点的集合,该集合内的任意两点没有边相连。

补图的最大独立集 = 二分图顶点数 - 二分图最大匹配数

然后问题就转化为了求这个二分图的补图的最大匹配数。这样就很简单啦.我使用的是匈牙利算法来求匹配数。

 

四、代码

#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <cstring>
#include <queue>
#include <list>
#include <cstdio>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cctype>
#include <sstream>
#include <iterator>
#include <functional>
#include <stdlib.h>
#include <time.h>
#include <bitset>
using namespace std;
#define LL long long
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; }
const int maxv = 1011;


int T;
int P, N;
int uN;
int match[100];
bool visit[100];
bool vec[100][100];
int find(int u)
{
	for (int i = 21; i <= 20 + P; i++)		
	{
		if (vec[u][i]&&!visit[i])
		{
			visit[i] = 1;
			if (match[i] == -1 || find(match[i]))
			{
				match[i] = u;
				return true;
			}
		}
	}
	return false;
}
int Match()
{
	int ans = 0;
	memset(match, -1, sizeof(match));
	for (int i = 1; i <= uN; i++)
	{
		memset(visit, 0, sizeof(visit));
		if (find(i))
			ans++;
	}
	return ans;
}
int main()
{
	scanf("%d", &T);
	while (T--)
	{
		memset(visit, false, sizeof(visit));
		memset(vec, false , sizeof(vec));
		scanf("%d %d", &P, &N);
		uN = P;
		for (int i = 1; i <= N; i++)
		{
			int u, v;
			scanf("%d %d", &u, &v);
			v += 20;
			vec[u][v] = true;
		}
		//读入原图
		for (int i = 1; i <= P; i++)
		{
			for (int j = 21; j <= 20 + P; j++)
			{
				vec[i][j] = !vec[i][j];
			}
		}
		//将原图取为补图
		int ans = 2 * P - Match();
		printf("%d\n", ans);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值