二分匹配好博客:http://blog.csdn.net/xu3737284/article/details/8973720,https://www.byvoid.com/blog/hungary
http://blog.csdn.net/thundermrbird/article/details/52231639,http://dsqiu.iteye.com/blog/1689505
匈牙利算法可以解决的图的问题:(二分图)
1.图的最小点覆盖数 = 图的最大匹配数;
2.图的最大点独立集 = 图顶点数 - 图的最大匹配数;
3.图的最小路径覆盖数 = 原图的顶点数 - 原图拆点后形成的二部图的最大匹配数/2;(无向无环图)
4.图的最小路径覆盖数 = 原图的顶点数 - 最大匹配数;(有向无环图)
无向无环图的最小路径覆盖:拆成两个点i1和i2,比如i和j连,拆后变成i1--〉j2,j1--〉i2
二分匹配一题,最大匹配
题目:hdu 4160
题意:给定一些长方体,小的长方体可以放进大的长方体,而且保证输入一定是按照长、宽、高进行输入,保证长大于长,宽大于宽,高大于高才能放入,求最后能剩几个长方体可见
题解:最小路径覆盖,求最大匹配(匈牙利算法o(n*e))
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
//const int N=600;
typedef struct
{
int a,b,c;
}Node;
Node node[600];
int head[600*2];
typedef struct
{
int to,next;
}Edge;
Edge edge[600*600];
int match[600*2];
bool vis[600*2];
bool dfs(int root)
{
for(int i=head[root];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!vis[v])
{
vis[v]=1;
if(match[v]==-1 ||dfs(match[v]))
{
match[v]=root;
return true;
}
}
}
return false;
}
int main()
{
int n;
while(~scanf("%d",&n) && n)
{
for(int i=1;i<=n;i++)
{
scanf("%d %d %d",&node[i].a,&node[i].b,&node[i].c);
}
int cnt=1;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(node[i].a<node[j].a && node[i].b<node[j].b && node[i].c<node[j].c)
{
edge[cnt].to=j+600;//注意这,要将两个分开,当成两个点,唯一的改变点
edge[cnt].next=head[i];
head[i]=cnt++;
}
}
}
int ans=0;
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
printf("%d\n",n-ans);
}
return 0;
}
待续........