匈牙利算法

来源:互联网 发布:win7 禁止卸载软件 编辑:程序博客网 时间:2024/05/29 19:24
匈牙利算法
http://blog.csdn.net/dark_scope/article/details/8880547趣写算法

http://blog.csdn.net/acdreamers/article/details/8621130匈牙利算法


(1)二分图的最小顶点覆盖 
最小顶点覆盖要求用最少的点(X或Y中都行),让每条边都至少和其中一个点关联。
Knoig定理:二分图的最小顶点覆盖数等于二分图的最大匹配数。


(2)DAG图的最小路径覆盖 
用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点,这就是DAG图的最小路径覆盖问题。
结论:DAG图的最小路径覆盖数 = 节点数(n)- 最大匹配数(m)


(3)二分图的最大独立集
最大独立集问题: 在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值
结论:二分图的最大独立集数 = 节点数(n)— 最大匹配数(m)


POJ  1469

#include <iostream>#include <cstring>#define maxnum 355using namespace std;int vis[maxnum];int link[maxnum];int head[maxnum];int cnt;struct node{int v;int next;}list[maxnum*maxnum];void init(){cnt = 0;memset(head,-1,sizeof(head));}void add(int u,int v){list[cnt].v = v;list[cnt].next = head[u];head[u] = cnt++;}int find(int u){int i;for(i=head[u];~i;i=list[i].next){int v = list[i].v;if(!vis[v]){vis[v] = 1;if(link[v] == -1 || find(link[v])){link[v] = u;return 1;}}}return 0;}int match(int N){int i,sum=0;memset(link,-1,sizeof(link));for(i=1;i<=N;i++){memset(vis,0,sizeof(vis));if(find(i))sum++;}return sum;}int main(){int i,j,k,kk;int a,b;int len;int u,v;int p,n,N;scanf("%d",&N);while(N--){scanf("%d%d",&p,&n);init();for(i=1;i<=p;i++){scanf("%d",&k);while(k--){scanf("%d",&v);add(i,v);}}int t = match(p);printf(t==p?"YES\n":"NO\n");}return 0;}

POJ 3041

#include <iostream>#include <cstring>#define maxnum 555using namespace std;int vis[maxnum];int link[maxnum];int head[maxnum];int cnt;struct node{int v;int next;}list[maxnum*maxnum];void init(){cnt = 0;memset(head,-1,sizeof(head));}void add(int u,int v){list[cnt].v = v;list[cnt].next = head[u];head[u] = cnt++;}int find(int u){int i;for(i=head[u];~i;i=list[i].next){int v = list[i].v;if(!vis[v]){vis[v] = 1;if(link[v] == -1 || find(link[v])){link[v] = u;return 1;}}}return 0;}


0 0
原创粉丝点击