hiho1122_二分图匈牙利算法
题目
给定一个图的N个节点和节点之间的M条边,数据保证该图可以构成一个二分图。求该二分图最大匹配。
题目链接:二分图最大匹配
首先通过染色法,将图的N个节点分成两个部分;然后通过匈牙利算法求二分图的最大匹配。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include<stdio.h> #include<string.h> #include<iostream> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<stack> #include<unordered_map> #include<unordered_set> #include<algorithm> using namespace std; struct Edge{ int to; int next; }; Edge gEdges[80005]; int gEdgeIndex; int gHead[10005]; int gMatch[10005]; bool gVisited[10005]; int gColor[10005]; bool conflict; void Init(){ gEdgeIndex = 0; memset(gHead, -1, sizeof (gHead)); memset(gVisited, false , sizeof (gVisited)); memset(gMatch, -1, sizeof (gMatch)); memset(gColor, -1, sizeof (gColor)); conflict = false ; } void InsertEdge( int u, int v){ int e = gEdgeIndex++; gEdges[e].to = v; gEdges[e].next = gHead[u]; gHead[u] = e; } void PaintColor( int node, int c){ if (conflict) return ; gColor[node] = c; for ( int e = gHead[node]; e != -1; e = gEdges[e].next){ int x = gEdges[e].to; if (gColor[x] == c){ conflict = true ; return ; } if (gColor[x] == -1) PaintColor(x, 1 - c); } } bool Dfs( int node){ for ( int e = gHead[node]; e != -1; e = gEdges[e].next){ int v = gEdges[e].to; if (!gVisited[v]){ gVisited[v] = true ; //置位 if (gMatch[v] == -1){ //如果对方的阵营中v点还没有匹配,则成功找到一条交错路径 gMatch[node] = v; gMatch[v] = node; return true ; } else if (Dfs(gMatch[v])){ //如果对方阵营中v有匹配点,匹配点肯定在己方阵营,则继续从己方阵营的点 //递归 gMatch[node] = v; gMatch[v] = node; return true ; } } } return false ; } int main(){ int n, m, u, v; Init(); scanf( "%d %d" , &n, &m); for ( int i = 0; i < m; i++){ scanf( "%d %d" , &u, &v); InsertEdge(u, v); InsertEdge(v, u); } for ( int i = 1; i <= n; i++) if (gColor[i] == -1) PaintColor(i, 0); int ans = 0; for ( int i = 1; i <= n; i++){ if (gColor[i] == 0 && gMatch[i] == -1){ //从固定一方阵营中,不断找未匹配点 //寻找交错路,找到一条交错路,则匹配个数增加1 memset(gVisited, false , sizeof (gVisited)); if (Dfs(i)) ans++; } } printf( "%d\n" , ans); return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步