• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-72  評論-126  文章-0  trackbacks-0
            今天學了KM算法,用于二分圖的完美匹配,以前就遇到過很多次,但是一直都沒有花時間去學
            學的比較挫,寫的是n^4的算法
            實際上有m*m*n的算法的
            下邊幾道是完美匹配的題目
            http://info.zjfc.edu.cn/acm/problemDetail.aspx?pid=1222 赤裸裸的完美匹配,圖都建好了
            http://acm.hdu.edu.cn/showproblem.php?pid=1533 這個建圖很容易
            http://acm.hdu.edu.cn/showproblem.php?pid=2282 這個需要建圖

            下邊是http://acm.hdu.edu.cn/showproblem.php?pid=1533 的AC代碼
            //////////////////////////////////////////////////////////////////////////
            //二分圖的完美匹配,Kuhn-Munkras算法
            #include<stdio.h>
            #include
            <math.h>
            #include
            <string>
            #define MAXN 101
            //////////////////////////////////////////////////////////////////////////
            #define inf 0x7FFFFFFF
            int edge[MAXN][MAXN];
            int match[MAXN];
            bool hash[MAXN][MAXN];
            bool xhash[MAXN],yhash[MAXN];
            char map[MAXN][MAXN];
            int min(int a,int b){return a>b?b:a;}
            int max(int a,int b){return a>b?a:b;}
            void Scanf(int n,int m,int &l);
            bool dfs(int p,int n)//找增廣路徑
            {
                
            int i;
                
            for(i=0;i<n;i++)
                {
                    
            if(!yhash[i] && hash[p][i])
                    {
                        yhash[i] 
            = true;
                        
            int t = match[i];
                        
            if(t == -1 || dfs(t,n))
                        {
                            match[i] 
            = p;
                            
            return true;
                        }
                        
            if(t != -1)
                            xhash[t] 
            = true;
                    }
                }
                
            return false;
            }
            void show(int id,int n)
            {
                
            int i,j;
                
            for(i=0;i<n;i++)
                {
                    
            for(j=0;j<n;j++)
                    {
                        
            if(id)
                            printf(
            "%d ",edge[i][j]);
                        
            else
                            printf(
            "%d ",hash[i][j]);
                    }
                    puts(
            "");
                }
                puts(
            "");
            }
            void KM_Perfect_Match(int n)
            {
                
            int i,j;
                
            int xl[MAXN],yl[MAXN];
                
            for(i=0;i<n;i++)
                {
                    xl[i] 
            = 0;
                    yl[i] 
            = 0;
                    
            for(j=0;j<n;j++)
                        xl[i] 
            = max(xl[i],edge[i][j]);
                }
                
            bool perfect = false;
                
            while(!perfect)
                {
                    
            for(i=0;i<n;i++)//現階段已經匹配的路
                    {
                        
            for(j=0;j<n;j++)
                        {
                            
            if(xl[i] + yl[j] == edge[i][j])
                                hash[i][j] 
            = true;
                            
            else
                                hash[i][j] 
            = false;
                        }
                    }

            //        show(0,n);
                    int cnt = 0;
                    memset(match,
            -1,sizeof(match));
                    
            for(i=0;i<n;i++)//當前的圖是否能全部匹配
                    {
                        memset(xhash,
            false,sizeof(xhash));
                        memset(yhash,
            false,sizeof(yhash));
                        
            if(dfs(i,n))
                            cnt 
            ++;
                        
            else
                        {
                            xhash[i] 
            = true;
                            
            break;
                        }
                    }
                    
            if(cnt == n)//沒有增廣路徑
                        perfect = true;
                    
            else
                    {
                        
            int ex = inf;
                        
            for(i=0;i<n;i++)
                        {
                            
            for(j=0;xhash[i] && j<n;j++)
                            {
                                
            if(!yhash[j])
                                    ex 
            = min(ex,xl[i] + yl[j] - edge[i][j]);//找到一條沒建的邊的最小值
                            }
                        }
                        
            for(i=0;i<n;i++)//根據這個邊來進行松弛
                        {
                            
            if(xhash[i])
                                xl[i] 
            -= ex;
                            
            if(yhash[i])
                                yl[i] 
            += ex;
                        }
                    }
                }
            }
            int main()
            {
                
            int n,m,l;
                
            while(scanf("%d%d",&n,&m))
                {
                    
            if(n == 0 && m == 0)
                        
            break;
                    Scanf(n,m,l);
                    KM_Perfect_Match(l);
                    
            int mindis = 0;
                    
            for(int i=0;i<l;i++)
                        mindis 
            += edge[match[i]][i];
                    printf(
            "%d\n",-mindis);
                }
                
            return 0;
            }

            //讀入建圖
            void Scanf(int n,int m,int &l)
            {
                
            int i,j,l1,l2;
                
            struct Point{
                    
            int x,y;
                }MAN[MAXN],HOUSE[MAXN];
                l1 
            = l2 = 0;
                
            for(i=0;i<n;i++)
                {
                    scanf(
            "%s",map[i]);
                    
            for(j=0;j<m;j++)
                    {
                        
            if(map[i][j]=='m')
                        {
                            MAN[l1].x 
            = i;
                            MAN[l1].y 
            = j;
                            l1 
            ++;
                        }
                        
            else if(map[i][j]=='H')
                        {
                            HOUSE[l2].x 
            = i;
                            HOUSE[l2].y 
            = j;
                            l2 
            ++;
                        }
                    }
                }
                l 
            = l1;
                
            for(i=0;i<l;i++)
                    
            for(j=0;j<l;j++)
                        edge[i][j] 
            = -abs(MAN[i].x - HOUSE[j].x) - abs(MAN[i].y - HOUSE[j].y);
            }

            posted on 2009-04-21 14:32 shǎ崽 閱讀(1754) 評論(2)  編輯 收藏 引用

            評論:
            # re: 二分圖的完美匹配 2009-04-24 18:48 | wswyb001
            好長啊,還沒有學KM  回復  更多評論
              
            # re: 二分圖的完美匹配 2009-04-28 14:42 | shǎ崽
            @wswyb001
            這個是n^4的算法
            浙大模板n^3的,現在用那個。。。  回復  更多評論
              
            久久综合偷偷噜噜噜色| 久久综合亚洲色一区二区三区 | 人妻丰满?V无码久久不卡| 久久青草国产手机看片福利盒子| 久久精品国产清高在天天线| 97久久超碰成人精品网站| 亚洲国产天堂久久综合网站| 久久午夜无码鲁丝片午夜精品| 久久久久波多野结衣高潮| 日韩精品久久无码人妻中文字幕| 青青草国产精品久久| 亚洲国产成人乱码精品女人久久久不卡| 一级a性色生活片久久无少妇一级婬片免费放| 久久乐国产综合亚洲精品| 久久久久免费看成人影片| 久久伊人色| 99久久精品国产高清一区二区 | 久久精品国产黑森林| 伊人久久精品影院| 国产ww久久久久久久久久| 久久亚洲精品成人无码网站| 天天久久狠狠色综合| 久久国产免费直播| 久久男人AV资源网站| 久久亚洲国产午夜精品理论片| 精品久久久久久久久免费影院| 91麻精品国产91久久久久| 久久综合给合久久国产免费 | 99久久超碰中文字幕伊人| 久久乐国产精品亚洲综合| 色成年激情久久综合| 国产精品久久国产精麻豆99网站| 无码人妻少妇久久中文字幕蜜桃 | 久久亚洲日韩精品一区二区三区 | 精品国产乱码久久久久久1区2区 | 久久精品久久久久观看99水蜜桃| 久久香蕉综合色一综合色88| 久久777国产线看观看精品| 精品久久人人爽天天玩人人妻| 伊人久久成人成综合网222| 久久亚洲天堂|