标签:map vector 相交 tor 匹配 tle pop 入队 printf
1 //Hopcroft-Karp 算法 时间复杂度为O(n^(1/2)*m) 2 //该算法是对匈牙利算法的优化,利用匈牙利算法一次只能找到一条增广路径, 3 //Hopcroft-Karp就提出一次找到多条不相交的增广路径(不相交就是没有公共点和公共边的增广路径),称为增广路集 4 //然后根据这些增广路径添加多个匹配,并逐渐增加增广路径集中增广路径的长度。 5 #include <iostream> 6 #include <stdio.h> 7 #include <cstring> 8 #include <cmath> 9 #include <vector> 10 //#include <map> 11 #include <queue> 12 #include <set> 13 #define MAX 3003 14 #define INF 0x3f3f3f3f 15 16 using namespace std; 17 int nextLeft[MAX],nextRight[MAX]; //nextLeft[MAX]是左集合匹配右集合的点,同理nextRight也是 18 int dLeft[MAX],dRight[MAX]; //dLeft[MAX],dRight[MAX]是增广路径长度,或者说BFS深度 19 int dx[MAX],dy[MAX]; 20 int map[MAX][MAX]; //map[MAX][MAX]存图 21 int nx,ny; //nx,ny分别是左集合点个数,右集合点个数 22 int dis; 23 int vis[MAX]; //标记数组. 24 25 bool searchPath() { //寻找增广路径集,其增广路径集中每条增广路径长度一样 26 queue<int>Q; 27 dis = INF; 28 memset(dLeft,-1,sizeof(dLeft)); 29 memset(dRight,-1,sizeof(dRight)); 30 for (int i = 1;i <= nx; i++) { //在BFS中宽度搜索 31 if (-1 == nextLeft[i]) { //将未遍历的节点 入队 并初始化次节点距离为0 32 Q.push(i); 33 dLeft[i] = 0; 34 } 35 } 36 while (!Q.empty()) { //广度搜索增广路径 37 int u = Q.front(); 38 Q.pop(); 39 if (dLeft[u] > dis) break; 40 for (int v = 1; v <= ny; v++) { //取右侧节点 41 if (map[u][v] && -1==dRight[v]) { //右侧节点的增广路径的距离 42 dRight[v] = dLeft[u]+1; //v对应的距离 为u对应距离加1 43 if (-1 == nextRight[v]) dis = dRight[v]; 44 else { 45 dLeft[nextRight[v]] = dRight[v]+1; 46 Q.push(nextRight[v]); 47 } 48 } 49 } 50 } 51 return dis != INF; 52 } 53 bool Find(int u) { //Find函数,对增广路径集进行增广。 54 for (int v = 1; v <= ny; v++) { 55 if (!vis[v] && map[u][v] && dRight[v] == dLeft[u]+1) { 56 vis[v] = 1; 57 if (nextRight[v] != -1 && dRight[v] == dis) continue; 58 if (-1 == nextRight[v] || Find(nextRight[v])) { 59 nextRight[v] = u;nextLeft[u] = v; 60 return true; 61 } 62 } 63 } 64 return false; 65 } 66 int MaxMatch() { 67 int ans(0); 68 memset(nextRight,-1,sizeof(nextRight)); 69 memset(nextLeft,-1,sizeof(nextLeft)); 70 while(searchPath()) { //不断进行增广路径集的操作,其增广路径也不断增长。 71 memset(vis,0,sizeof(vis)); 72 for (int i = 1; i <= nx; i++) { 73 if (-1 == nextLeft[i]) { 74 if (Find(i)) ans++; 75 } 76 } 77 } 78 return ans; 79 } 80 81 int main(int argc,char *argv[]) { 82 // int n,m,e; 83 int e; 84 scanf("%d%d%d", &nx,&ny,&e); 85 for (int i = 1; i <= e; i++) { 86 int u,v; 87 scanf("%d%d", &u,&v); 88 if (u>=1&&u<=nx&&v>=1&&v<=ny) { 89 map[u][v] = 1; 90 } 91 } 92 printf("%d\n", MaxMatch()); 93 return 0; 94 }
标签:map vector 相交 tor 匹配 tle pop 入队 printf
原文地址:https://www.cnblogs.com/AyOh-loop/p/11450957.html