最大二分匹配
2014-03-04 23:24
281 查看
最大二分匹配
匈牙利算法 hungary
算法不难,难点在于建图。下面有几种常见的用hungary算法解决的问题。
1.最小顶点覆盖 :二分图的最小顶点覆盖数 =二分图的最大匹配数。HDU 1150
2.DAG图的最小路径覆盖:DAG图的最小路径覆盖数=节点数(n)- 最大匹配数(m)HDU 1151
3.二分图的最大独立集:二分图的最大独立集数=节点数(n)— 最大匹配数(m)HDU 1068
hdu 1507 最大二分匹配
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 150
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int map[maxn][maxn];
int vis[maxn*maxn];
int pat[maxn*maxn];
int n,m;
int hungary(int state)
{
int x=state/m;
int y=state%m;
for(int i=0;i<4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
int S=tx*m+ty;
if(tx<n&&tx>=0&&ty<m&&ty>=0&&vis[S]==0&&map[tx][ty]==0)
{
vis[S]=1;
if(pat[S]==-1||hungary(pat[S]))
{
pat[S]=state;
return 1;
}
}
}
return 0;
}
int main()
{
int x,y;
while(cin>>n>>m&&n+m)
{
int k;
memset(pat,-1,sizeof(pat));
memset(map,0,sizeof(map));
cin>>k;
for(int i=0;i<k;i++)
{
cin>>x>>y;
map[--x][--y]=1;
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if((i+j)&1&&map[i][j]==0)
{
memset(vis,0,sizeof(vis));
ans+=hungary(i*m+j);
}
cout<<ans<<endl;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(pat[i*m+j]!=-1)
printf("(%d,%d)--(%d,%d)\n",1+i,j+1,pat[i*m+j]/m+1,1+pat[i*m+j]%m);
}
return 0;
}
匈牙利算法 hungary
int hungary(int x) { for(int i=1;i<=n;i++) if(vis[i]==0&&map[x][i]) { vis[i]=1; if(pat[i]==-1||hungary(pat[i])) { pat[i]=x; return 1; } } return 0; }
算法不难,难点在于建图。下面有几种常见的用hungary算法解决的问题。
1.最小顶点覆盖 :二分图的最小顶点覆盖数 =二分图的最大匹配数。HDU 1150
2.DAG图的最小路径覆盖:DAG图的最小路径覆盖数=节点数(n)- 最大匹配数(m)HDU 1151
3.二分图的最大独立集:二分图的最大独立集数=节点数(n)— 最大匹配数(m)HDU 1068
hdu 1507 最大二分匹配
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 150
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int map[maxn][maxn];
int vis[maxn*maxn];
int pat[maxn*maxn];
int n,m;
int hungary(int state)
{
int x=state/m;
int y=state%m;
for(int i=0;i<4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
int S=tx*m+ty;
if(tx<n&&tx>=0&&ty<m&&ty>=0&&vis[S]==0&&map[tx][ty]==0)
{
vis[S]=1;
if(pat[S]==-1||hungary(pat[S]))
{
pat[S]=state;
return 1;
}
}
}
return 0;
}
int main()
{
int x,y;
while(cin>>n>>m&&n+m)
{
int k;
memset(pat,-1,sizeof(pat));
memset(map,0,sizeof(map));
cin>>k;
for(int i=0;i<k;i++)
{
cin>>x>>y;
map[--x][--y]=1;
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if((i+j)&1&&map[i][j]==0)
{
memset(vis,0,sizeof(vis));
ans+=hungary(i*m+j);
}
cout<<ans<<endl;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(pat[i*m+j]!=-1)
printf("(%d,%d)--(%d,%d)\n",1+i,j+1,pat[i*m+j]/m+1,1+pat[i*m+j]%m);
}
return 0;
}
相关文章推荐
- 二分最大匹配(匈牙利算法+HK算法)
- HDU 1151Air Raid 最小路径覆盖=n-最大匹配量 (第二道二分匹配)
- UVA 11419 SAM I AM(最大二分匹配&最小点覆盖:König定理)
- 最大二分匹配 ZQUOJ21474 && POJ1486 Sorting Slides
- 08-25 USACO 4.1~4.2 搜索,最大流,二分匹配
- 【最大权二分匹配的KM算法】
- HDU 1498 50 years, 50 colors(匈牙利算法 二分最大匹配数)
- POJ 2226 Muddy Fields(二分匹配【最大流】)
- HDU 2458 最大团个数=顶点数 - 补图最大匹配数 二分匹配
- poj3692Kindergarten 二分匹配之最大独立集
- HDU1507(最大二分匹配)
- HDU1528(最大二分匹配)
- uva 10122 Mysterious Mountain and ZOJ 1231 Mysterious Mountain (二分+二部图最大匹配)
- 利用匈牙利算法&Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES
- 2014上海邀请赛D Battle ships(最大二分匹配)
- poj 2239 Selecting Courses 最大二分匹配
- poj 1719最大二分匹配hungary算法
- 【POJ3020】【总数-最大二分匹配】【最小路径覆盖和点覆盖的区别是 路径的话要所有点覆盖了】
- hrbust 1469 Wrong Answer【最大独立集---二分匹配】
- 【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)