二分最大匹配总结(没有价值含量,个人留个纪念)
2014-04-20 21:40
393 查看
HDU 2444 黑白染色 ,二分图判定
const int maxn = 208 ; vector<int> g[maxn] ; int n ; bool vis[maxn] ; int match[maxn] ;; int color[maxn] ; int setcolor(int u , int c){ color[u] = c ; for(vector<int>::iterator it = g[u].begin() ; it != g[u].end() ; it++){ if(color[*it] == -1) { if(! setcolor(*it , c^1)) return 0 ; } else if(color[*it] == color[u]) return 0 ; } return 1 ; } int judge(){ for(int i = 1 ; i <= n ; i++){ if(color[i] == -1){ if(! setcolor(i , 0)) return 0 ; } } return 1 ; } int dfs(int u){ for(vector<int>::iterator it = g[u].begin() ; it != g[u].end() ; it++){ if(vis[*it]) continue ; vis[*it] = 1 ; if(match[*it] == -1 || dfs(match[*it])){ match[*it] = u ; return 1 ; } } return 0 ; } int maxmatch(){ int ans = 0 , u ; memset(match , -1 , sizeof(match)) ; for(u = 1 ; u <= n ; u++){ memset(vis , 0 , sizeof(vis)) ; if(dfs(u)) ans++ ; } return ans ; } int main(){ int m , i , j , u , v ; while(cin>>n>>m){ for(i = 1 ; i <= n ; i++) g[i].clear() ; for(i = 1 ; i <= m ; i++){ scanf("%d%d" ,&u,&v) ; g[u].push_back(v) ; g[v].push_back(u) ; } for(i = 1 ; i <= n ; i++) color[i] = -1 ; if(judge()) printf("%d\n" , maxmatch() >> 1) ; else puts("No") ; } return 0 ; }
HDU 4185 在一个N*N的矩阵里寻找最多有多少个“##”(横着竖着都行)
很典型的二分匹配问题,将矩阵中的点分成俩种,下标i+j为奇数和偶数俩种,即把矩阵当成一个黑白棋盘,那么,一个木板只能覆盖一个黑色和一个白色格子,将黑色格子(并且是‘#’的格子)跟相邻的白色(并且是‘#’)的格子连一条边,则变成了一个求最大匹配的问题了const int maxn = 601*601*2 ; int n , m ; vector<int> g[maxn] ; int match[maxn] ; bool vis[maxn] ; int dfs(int u){ for(vector<int>::iterator it = g[u].begin() ; it != g[u].end() ; it++){ if(vis[*it]) continue ; vis[*it] = 1 ; if(match[*it] == -1 || dfs(match[*it])){ match[*it] = u ; return 1 ; } } return 0 ; } int maxmatch(){ int ans = 0 , u ; memset(match , -1 , (m+1)*sizeof(int)) ; for(u = 1 ; u <= n ; u++){ memset(vis , 0 , (m+1)*sizeof(bool)) ; if(dfs(u)) ans++ ; } return ans ; } char str[608][608] ; int N ; map<int ,int> A , B ; int d[4][2] = {{-1,0},{1,0},{0,-1},{0,1}} ; inline int can(int x , int y){ return 1 <= x && x<= N && 1 <= y && y <= N && str[x][y] == '#' ; } int code(int x , int y){ return (x-1)*N + y ; } int main(){ int t , i , j , u , v , indxA , indxB ,k, x , y , T = 1 ; cin>>t ; while(t--){ scanf("%d" ,&N) ; for(i = 1 ; i <= N ; i++) scanf("%s" ,str[i]+1) ; A.clear() , B.clear() ; indxA = indxB = 0 ; for(i = 1 ; i <= N ; i++){ for(j = 1 ; j <= N ; j++){ if(((i+j)&1) && str[i][j] == '#'){ for(k = 0 ; k < 4 ; k++){ x = i + d[k][0] ; y = j + d[k][1] ; if(can(x,y)){ u = code(i , j) ; v = code(x , y) ; if(A.find(u) == A.end()) A[u] = ++indxA ; if(B.find(v) == B.end()) B[v] = ++indxB ; g[A[u]].push_back(B[v]) ; } } } } } n = indxA ; m = indxB ; printf("Case %d: %d\n" , T++ , maxmatch() ) ; for(i = 1 ; i <= n ; i++) g[i].clear() ; } return 0 ; }
相关文章推荐
- 二分匹配总结(匈牙利算法+最大权+最小权)
- 二分匹配总结(匈牙利算法+最大权+最小权)
- 二分匹配总结(匈牙利算法+最大权+最小权)
- 二分匹配 模版 及最大总结 及 题目集合 +解析
- HDU 2444 The Accomodation of Students 判断是否为二分图,二分图的最大匹配
- 二分匹配总结
- cf Two Sets (我用二分最大匹配做的)
- 二分图最大匹配总结
- ZOJ 1516 Uncle Tom's Inherited Land(二分匹配 最大匹配 匈牙利啊)
- hdu 2119 Matrix(二分最大匹配)
- HDU 4619 Warm up 2(最大流或二分匹配)
- ZOJ 1654 Place the Robots(最大二分匹配)
- POJ 3041 Asteroids(最大二分匹配)
- 最大流练习:Graduation,二分匹配
- UVa live3415Guardian of Decency(二分最大匹配之最大独立点集)
- UVa live3126Taxi Cab Scheme(二分最大匹配之最小路径覆盖)
- 二分最大匹配 匈牙利算法
- HDU1528 Card Game Cheater 二分匹配最大点覆盖问题
- 最大权二分匹配(最大费用流) —— Best couple (玲珑学院 1047)
- 【算法小总结】二分图最大匹配的非递归方法