(点的配对)二分图最大匹配
Posted calculus9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(点的配对)二分图最大匹配相关的知识,希望对你有一定的参考价值。
传送门:https://abc091.contest.atcoder.jp/tasks/arc092_a?lang=en
题目:On a two-dimensional plane, there are N red points and N blue points. The coordinates of the i-th red point are (ai, bi), and the coordinates of the i-th blue point are (c_i, d_i).
A red point and a blue point can form a friendly pair when, the x-coordinate of the red point is smaller than that of the blue point, and the y-coordinate of the red point is also smaller than that of the blue point.
At most how many friendly pairs can you form? Note that a point cannot belong to multiple pairs.
题意:平面上有n个红点和n个蓝点,红点和蓝点间配对。如果点a和点b,a是红点,b是蓝点,a在b的左下角,即a的x及y坐标都比b的小,那么这两点就可以配对,已经配对的两点不能再和其它点配对,求最多可以配多少对
思路:因为当a的x和y都比b的小的时候,这两点可以配对,即代表两者之间可以建边(这里用flag数组标记一下)。
1 /*最大匹配:①建图加边②遍历左半部的点依次判断其匹配 ③find*/ 2 /*先到先得,能让就让*/ 3 #include<iostream> 4 using namespace std; 5 const int N=110; 6 int match[N];//右边的点对应的值 7 bool vis[N],flag[N][N];//vis判重 有没有找过 8 struct node { 9 int x,y; 10 }r[N],b[N];//红色和蓝色的点 11 int n; 12 bool find(int x)//给对应的红色点找蓝色的点 13 { 14 for(int i=1;i<=n;i++)//枚举所有蓝色的点 15 { 16 if(!vis[i]&&flag[x][i])//该蓝色的点未被查看过并且能与红色点匹配 17 { 18 vis[i]=1; 19 if(match[i]==0||find(match[i])) 20 {//该蓝色的点未被匹配过||该蓝色的点被匹配过了但是红色的点还可以匹配其他的 21 match[i]=x; 22 return 1; 23 } 24 } 25 } 26 return 0; 27 } 28 int main()//主函数 29 { 30 cin>>n; 31 for(int i=1;i<=n;i++) cin>>r[i].x>>r[i].y; 32 for(int i=1;i<=n;i++) cin>>b[i].x>>b[i].y; 33 for(int i=1;i<=n;i++) 34 { 35 for(int j=1;j<=n;j++) 36 { 37 if(r[i].x<b[j].x&&r[i].y<b[j].y) 38 { 39 flag[i][j]=1;//两者可以配对 40 } 41 } 42 } 43 long long ans=0; 44 for(int i=1;i<=n;i++) 45 { 46 memset(vis,0,sizeof(vis)); 47 if(find(i))//最大匹配 48 ans++; 49 } 50 cout<<ans<<endl; 51 }
以上是关于(点的配对)二分图最大匹配的主要内容,如果未能解决你的问题,请参考以下文章