二分图简单概念&&HDU 2063
Posted 十年换你一句好久不见
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图简单概念&&HDU 2063相关的知识,希望对你有一定的参考价值。
二分图:
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
简单的说,一个图被分成了两部分,相同的部分没有边,那这个图就是二分图,二分图是特殊的图。
匹配:
给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。
极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配。选择这样的边数最大的子集称为图的最大匹配问题。
如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。
求二分图匹配可以用最大流(Maximal Flow)或者匈牙利算法(Hungarian Algorithm)
注意匈牙利算法,除了二分图多重匹配外在二分图匹配中都可以使用。
例题:HDU 2063
过山车
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23222 Accepted Submission(s): 10059
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <cstdlib> #include <iomanip> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; #define lowbit(x) (x&(-x)) #define max(x,y) (x>y?x:y) #define min(x,y) (x<y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define pi acos(-1.0) #define ei exp(1) #define PI 3.141592653589793238462 #define ios() ios::sync_with_stdio(false) #define INF 0x3f3f3f3f #define mem(a) (memset(a,0,sizeof(a))) typedef long long ll; int k,m,n,vis[550],x,y; int g[550][550],pos[550]; bool find(int x) { for(int i=1;i<=n;i++) { if(g[x][i]&&!vis[i])//有机会并且这个男生没有被标记 { vis[i]=1; if((pos[i]==0)/*这个男生还没有女生选*/|| find(pos[i])/*或者给已选了这个男生的女生从新在找一个男同伴*/) { pos[i]=x; return true;//能找到,返回真; } } } return false; } int main() { while(scanf("%d",&k)&&k) { scanf("%d %d",&m,&n); memset(g,0,sizeof(g)); memset(pos,0,sizeof(pos)); for(int i=0;i<k;i++) { scanf("%d%d",&x,&y); g[x][y]=1;//女生x不反对和男生ycp } int sum=0; for(int i=1;i<=m;i++) { memset(vis,0,sizeof(vis));//女n号; if(find(i)) sum++; } printf("%d\n",sum); } return 0; }
以上是关于二分图简单概念&&HDU 2063的主要内容,如果未能解决你的问题,请参考以下文章