二分图 最大匹配 入门题

来源:互联网 发布:淘宝任务有礼 编辑:程序博客网 时间:2024/06/05 00:10

【问题背景】

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

原创粉丝点击