课程
P2417
技术统计
难度 提高+/省选-
用时 1h
提交次数 7
unaccept 次数 5
ac次数 2
题意概括
是否可以完全匹配
数据范围
n ≤ 100 , m ≤ 20000 n\le 100,m\le20000 n≤100,m≤20000
解法一、
知识点
- 匈牙利算法
- 二分图匹配
解法概括
匈牙利算法的板子题(好像是匈牙利算法都是板子题)。而且显然我们将图分为学生,课堂两部分。
坑点
- 以后再也不信洛谷的TLE了,数组开得太大会增加运行时间,开得太小不re,给我TLE。。。
- 数组开10倍好了
代码实现
#include<cstdio>
#include<cstring>
#define maxn 200100
using namespace std;
inline int read()
{
int f=1,k=0;
char c=getchar();
while(c>'9'||c<'0')
{
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9')k=(k<<1)+(k<<3)+(c^48),c=getchar();
return f*k;
}
inline void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
struct edge
{
int nxt,to;
}p[maxn];
int cnt,n,m,T,P;
int head[maxn],match[maxn];
bool vis[maxn];
void add(int u,int v)
{
p[++cnt].nxt=head[u];
p[cnt].to=v;
head[u]=cnt;
}
bool dfs(int now)
{
for(int i=head[now];i;i=p[i].nxt)
{
int to=p[i].to;
if(!vis[to])
{
vis[to]=1;
if(!match[to]||dfs(match[to]))
{
match[to]=now;
return 1;
}
}
}
return 0;
}
int main()
{
T=read();
while(T--)
{
int ans=0;cnt=0;
memset(match,0,sizeof(match));
memset(p,0,sizeof(p));
memset(head,0,sizeof(head));
P=read();n=read();
for(int i=1;i<=P;i++)
{
int b;
m=read();
for(int j=1;j<=m;j++)
{
b=read();
add(i,b);
}
}
if(P>n){printf("NO\n");continue;}
for(int i=1;i<=P;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))ans++;
}
if(ans==P)printf("YES\n");
else printf("NO\n");
}
return 0;
}
解法二、
听说网络流也是可以搞一搞二分图匹配的哦
类似题目
- 二分图匹配模板
- 假期的宿舍