二分图的最大匹配匈牙利算法和最小支配集

求二分图最大匹配(指派问题)的匈牙利算法:  
谈匈牙利算法自然避不开Hall定理,即是:对于二部图G,存在一个匹配M,
使得X的所有顶点关于M饱和的充要条件是:对于X的任意一个子集A,和A邻接的点集为T(A),恒有:   |T(A)|   > =   |A|  
匈牙利算法是基于Hall定理中充分性证明的思想,其基本步骤为:  
1.任给初始匹配M;  
2.若X已饱和则结束,否则进行第3步;  
3.在X中找到一个非饱和顶点x0,作V1   ←   {x0},     V2   ←   Φ;  
4.若T(V1)   =   V2则因为无法匹配而停止,否则任选一点y   ∈T(V1)/V2;  
5.若y已饱和则转6,否则做一条从x0   →y的可增广道路P,M←M⊕E(P),转2;  
6.由于y已饱和,所以M中有一条边(y,z),作   V1   ←   V1   ∪{z},   V2   ←   V2   ∪   {y},   转4;

来自:http://www.csdn.net/develop/Article/19/19501.shtm

 

二分图的最大匹配匈牙利算法

#include
#include


#define   maxn   105

int   nx,ny,jobnum;
int   g[maxn][maxn];//邻接矩阵
int   ans;
int   sx[maxn],sy[maxn]
int   cx[maxn],cy[maxn];//X集v点匹配Y集u点,则有:cx[v]=u,cx[u]=v

int   path(int   u)
{
      sx[u]=1;
      int   v,i;
      for(v=1;v <=ny;v++)
            if(   (g[u][v]> 0)   &&   (!sy[v])   )
            {
                  sy[v]=1;
                  if(   (!cy[v])   ||   (path(cy[v]))   )
                  {
                        cx[u]=v;
                        cy[v]=u;
                        return   1;
                  }
            }
      return   0;
}

int   solve()
{
      ans=0;
      int   i,j;
      memset(cx,0,sizeof(cx));
      memset(cy,0,sizeof(cy));
      for(i=1;i <=nx;i++)
            if(!cx[i])
            {
                  memset(sx,0,sizeof(sx));
                  memset(sy,0,sizeof(sy));
                  ans+=path(i);
            }

      return   0;
}

int   main()
{
      ifstream   cin( "1364.in ");
      ofstream   cout( "1364.out ");
      int   i,j,k,l;

      while(cin> > nx,nx> 0)
      {
            cin> > ny> > jobnum;
            if(cin.fail())
                  return   0;
            memset(g,0,sizeof(g));
            for(k=0;k             {
                  cin> > l> > i> > j;
                  g[i][j]=1;
            }
            solve();
            cout <       }

      return   0;
}

 

最小支配集

  顶点集D是图G=(V,E)的支配集当且仅当对任意u∈V-D存在v∈D使(u,v)∈E.最小支配集问题是对给定图G找出使|D|最小的支配集D.当所给的图是一棵树T时,我们可以利用树的前序标号表示法设计出求最小支配集D的线性时间算法如下:
MIN-DOMINATE-SET(T)
begin
   for   i:=1   to   ndo
    cover[i]:=0;
   D:=;
   for   i:=ndownto   2   do
    if   cover[i]=0   then
     begin
      D:=D∪{parent[i]};
      cover[parent[i]]:=1;
      cover[parent[parent[i]]]:=1
     end
end;{MIN-DOMINATE-SET}
  最小支配集问题同样具有贪心选择性质和最优子结构性质,从而保证了算法MIN-DOMINATE-SET的正确性,算法所需的计算时间也是O(n).

来自:http://topic.csdn.net/u/20080928/14/4e7a079c-21c4-484b-ab80-3785beccd489.htm

你可能感兴趣的:(c++和vc)