不是匹配
时间限制:1000 ms | 内存限制:65535 KB
描述
有N个人,N个活动, 每个人只会对2个或者3个活动感兴趣,
每个活动也只有两个人或者两个活动对它兴趣,每个人参加一个
感兴趣的活动需要一天 ,且当天该活动被参加时,其他的人不能参加
如果每个人都参加完自己有兴趣的活动,应当怎样安排使得所用总天数时间最短
2<= N <=1000, 1<=m<=1000;
输入
一个数T 表示T 组数据
每组一个N表示人数,编号1 – N , 一个数 m ,接下来m 行每个两个数
x,y, 表示第 x 个人对第y个活动感兴趣
输出
每组输出一个整数,表示最少天数
样例输入
1
3 6
1 1
1 2
2 2
2 3
3 1
3 3
样例输出
2
来源
某校校赛
上传者
MQLYES
————————————————————————————————————————————
已经无力吐槽了,看到题目,第一个想法,肯定就是匹配。
所以想到用二分图,1A。
和二分图模板不一样的是,不是求最大匹配,而是求最大匹配的情况下,最大重叠数的大小(即为天数。)
————————————————————————————————————————————
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>map[1001];
int vis[1001];
int Ky[1001];
int ans[1001];
int num,m;
int find( int u )
{
int v;
for( int i=0; i<=map[u].size(); i++ )
{
v = map[u][i];
if( !vis[v] ){
vis[v] = 1;
ans[v]++;
if( Ky[v] == -1 || find(Ky[v]) )
{
Ky[v] = u;
return true;
}
}
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while( t-- )
{
int Max = 0;
scanf("%d%d",&num,&m);
memset(Ky,-1,sizeof(Ky));
memset(ans,0,sizeof(ans));
for( int i=1; i<=num; i++ )
{
map[i].clear();
}
for( int i=1; i<=m; i++ )
{
int a,b;
scanf("%d%d",&a,&b);
map[a].push_back(b);
Max = max(b,Max);
}
int cnt = 0;
for( int i=1; i<=num; i++ )
{
memset(vis,0,sizeof(vis));
find(i);
}
for( int i=1; i<=Max; i++ )
{
if( ans[i] > cnt){
cnt = ans[i];
}
}
printf("%d\n",cnt);
}
return 0;
}

本文介绍了一个基于二分图的最大匹配算法解决的问题:如何在保证每个人都能参与其感兴趣的活动的前提下,尽可能减少所需的总天数。通过调整传统的二分图匹配算法,以计算在达到最大匹配时的最大重叠数。
980

被折叠的 条评论
为什么被折叠?



