二分图 最大匹配 入门题

【问题背景】

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
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
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
#include
#include
#include 
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;
}

你可能感兴趣的:(caioj)