匈牙利算法與km

匈牙利:

bool find(int u)
{
	flag[u]=1;
	for(int i=head[u];i!=-1;i=edge[i].next)
	{
		int v=edge[i].v;
		if(!flag[v])
		{
			flag[v]=1;
			if(match[v]==0||find(match[v]))
			{
				match[v]=u;
				return true;
			}
		}	
	}
	return false;
}
int function()
{
	int ans=0;
	memset(match,0,sizeof(match));
	for(int i=1;i<=n;i++)
	{
		memset(flag,0,sizeof(flag));
		if(find(i))ans++;
	}
	return ans;
}

km:

bool dfs(int s) //匈牙利算法找增廣路徑
{
    visx[s]=1;
    for(int i=1;i<=cnty;i++) 
        if(!visy[i]){
            int t=wx[s]+wy[i]-dis[s][i];
            if(t==0) {
                visy[i]=1;
                if(linky[i]==0||dfs(linky[i])){
                    linkx[s]=i,linky[i]=s;
                    return true;
                }
            }
            else if(t>0)  //找出邊權與頂標和的最小的差值
            {
                if(t<minz)minz=t;
            }
        }
    return false;
}
void km()
{
    memset(linkx,0,sizeof linkx); //linkx[i]表示與X部中點i匹配的點
    memset(linky,0,sizeof linky);
    for(int i=1;i<=cntx;i++){
        while(1){
            minz=INF;
            memset(visx,0,sizeof visx);
            memset(visy,0,sizeof visy);
            if(dfs(i))break;
            for(int j=1;j<=cntx;j++)  //將交錯樹中X部的點的頂標減去minz
            if(visx[j])wx[j]-=minz;
            for(int j=1;j<=cnty;j++) //將交錯樹中Y部的點的頂標加上minz
            if(visy[j])wy[j]+=minz;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章