Gym 101915D(最大团)

传送门

题面:

D. Largest Group

time limit per test

2.0 s

memory limit per test

64 MB

input

standard input

output

standard output

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 gi meaning 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 N denoting 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, gi describing 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

Copy

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

output

Copy

5
4

题意:

    有p个男生和p个女生,男生和男生之间,女生和女生之间相互认识,现在男生女生之间有n个关系,每个关系代表男生a女生b是朋友,现在问你最多有多少个人可以互相成为朋友。

题目分析:

    很显然,题目中就是要让我们求出这个二分图的最大团。

    最大团的定义:对于一般图来说,团是一个顶点集合,且由该顶点集合诱导的子图是一个完全图,简单说,就是选出一些顶点,这些顶点两两之间都有边。最大团就是使得选出的这个顶点集合最大。

    而二分图的最大团=补图的最大独立集。而最大独立集=点数-最小点覆盖。

    知道上述定义套上匈牙利算法的板子即可。

代码:

#include <bits/stdc++.h>
#define maxn 50
using namespace std;
int g[maxn][maxn];
int linker[maxn];
bool used[maxn];
int p,n;
bool dfs(int u){//匈牙利算法
    for(int v=1;v<=p;v++){
        if(!g[u][v]&&!used[v]){//注意因为是最大团,因此需要算的是补集
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v])){
                linker[v]=u;
                return true;
            }
        }
    }
    return false;
}
void hungry(){
    int res=0;
    memset(linker,-1,sizeof(linker));
    for(int u=1;u<=p;u++){
        memset(used,false,sizeof(used));
        if(dfs(u)) res++;
    }
    cout<<2*p-res<<endl;//最大独立集=点数-最小点覆盖(最大权匹配)
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&p,&n);
        memset(g,0,sizeof(g));
        for(int i=0;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            g[a][b]=1;
        }
        hungry();
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值