【问题背景】
n只公牛和m只母牛,某些公牛和某些母牛互相喜欢。
但最后一只公牛只能和一只母牛建立一对一匹配。
要使得最后牛群匹配对数最大。
【输入】
第一行三个整数n, m,k( 1<= n, m <= 10000,0< k <= 100000)。
下来k行,每行两个整数 x,y,表示一条边,连接X集合中x点和Y集合的y点。
【输出】
input:
5 5 9
1 2
2 2
2 3
2 5
3 1
3 3
4 1
5 3
5 4
output
5
裸的最大匹配
#include<cstdio>
using namespace std;
struct edge{int to,next;}a[100001];
int n,m,k,part[10001],link[10001],lk,h[10001];
bool dfs(int x)
{
for (int i=h[x];i;i=a[i].next)
{
if (link[a[i].to]!=lk)
{
link[a[i].to]=lk;
if (!part[a[i].to]||dfs(part[a[i].to]))
{
part[a[i].to]=x;
return true;
}
}
}
return false;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int u,v;
for (int i=1;i<=k;i++)
{
scanf("%d%d",&u,&v);
a[i].to=v;
a[i].next=h[u];
h[u]=i;
}
lk=0;int ans=0;
for (int i=1;i<=n;i++)
{lk++;if (dfs(i)) ans++;}
printf("%d",ans);
return 0;
}
一个星期有7天,每天有12节课。
有n门课程,但是有些课程上课的时间是冲突的,
求最多能上多少门课程。
Input
第一行为整数 n (1 <= n <= 300), 表示课程的总数。下来n行表示n门课程的信息。每行第一个数为整数 t (1 <= t <= 7*12), 表示学生可以学习该门课程的时间段总数。下来t对整数,每对整数为 p (1
<= p <= 7) and q (1 <= q <= 12), 表示该门课程在每个星期的第p天的第q节课上课。
Output
输出一行,最多能上多少门课。
Sample Input
5
1 1 1
2 1 1 2 2
1 2 2
2 3 2 3 3
1 3 3
Sample Output
4
把课程向时间建边,不妨设有7*12=84个时间段
然后跑一次最大匹配即可
#include<cstdio>
using namespace std;
struct edge{int to,next;}a[25000];
int n,link[301],lk,part[101],h[301];
bool dfs(int x)
{
for (int i=h[x];i;i=a[i].next)
{
if (link[a[i].to]!=lk)
{
link[a[i].to]=lk;
if (!part[a[i].to]||dfs(part[a[i].to]))
{
part[a[i].to]=x;
return true;
}
}
}
return false;
}
int main()
{
scanf("%d",&n);
int t=0,cnt=0;lk=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&t);
int x,y;
for (int j=1;j<=t;j++)
{
scanf("%d%d",&x,&y);
a[++cnt].to=x*12+y;
a[cnt].next=h[i];
h[i]=cnt;
}
}
int ans=0;
for (int i=1;i<=n;i++)
{
lk++;if (dfs(i)) ans++;
}
printf("%d",ans);
return 0;
}
【题意】
地鼠(产自北美的一种地鼠)刚刚逃过了犬的危险,有面对一个新的天敌。
有n个地鼠,有m个地洞,地鼠和地洞都有坐标(x,y)。
现在 一只鹰要来抓地鼠了。如果地鼠在s秒内无法到达地洞就会被吃掉。
一个地洞只能容一只地鼠。地鼠跑的速度为v,
下来地鼠家族正在设计一个逃跑策略使得被吃掉的地鼠最少。
【输入格式】
多组数据。
每组数据第一行为四个整数(均小于100), n, m, s, v.
下来n行表示n个地鼠的坐标。
再下来m行表示m个地洞的坐标。
【输出格式】
输出被吃掉的地鼠的数目。
【样例输入】
2 2 5 10
1.0 1.0
2.0 2.0
100.0 100.0
20.0 20.0
【样例输出】
1
将地鼠能到的地洞连边,最大匹配即可
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
struct edge{int to,next;}a[100001];
int n,m,s,v,lk,link[101],h[101],part[101];
double x[101],y[101];
bool dfs(int p)
{
for (int i=h[p];i;i=a[i].next)
{
if (link[a[i].to]!=lk)
{
link[a[i].to]=lk;
if (!part[a[i].to]||dfs(part[a[i].to]))
{
part[a[i].to]=p;
return true;
}
}
}
return false;
}
int main()
{
while (scanf("%d%d%d%d",&n,&m,&s,&v)!=EOF)
{
memset(h,0,sizeof(h));
memset(part,0,sizeof(part));
for (int i=1;i<=n;i++)
scanf("%lf%lf",&x[i],&y[i]);
double u,u1;
int cnt=0;
for (int i=1;i<=m;i++)
{
scanf("%lf%lf",&u,&u1);
for (int j=1;j<=n;j++)
{
if ((u-x[j])*(u-x[j])+(u1-y[j])*(u1-y[j])<=s*v*s*v)
{
a[++cnt].to=i;
a[cnt].next=h[j];
h[j]=cnt;
}
}
}
int ans=0;
for (int i=1;i<=n;i++)
{
lk++;if (dfs(i)) ans++;
}
printf("%d\n",n-ans);
}
return 0;
}