• <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
            今天學(xué)了KM算法,用于二分圖的完美匹配,以前就遇到過很多次,但是一直都沒有花時間去學(xué)
            學(xué)的比較挫,寫的是n^4的算法
            實(shí)際上有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++)//現(xiàn)階段已經(jīng)匹配的路
                    {
                        
            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++)//當(dāng)前的圖是否能全部匹配
                    {
                        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++)//根據(jù)這個邊來進(jìn)行松弛
                        {
                            
            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ǎ崽 閱讀(1745) 評論(2)  編輯 收藏 引用

            評論:
            # re: 二分圖的完美匹配 2009-04-24 18:48 | wswyb001
            好長啊,還沒有學(xué)KM  回復(fù)  更多評論
              
            # re: 二分圖的完美匹配 2009-04-28 14:42 | shǎ崽
            @wswyb001
            這個是n^4的算法
            浙大模板n^3的,現(xiàn)在用那個。。。  回復(fù)  更多評論
              

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            国产欧美久久久精品影院| 久久亚洲国产欧洲精品一| 亚洲中文久久精品无码ww16| 久久91精品国产91久久麻豆| 久久国产精品波多野结衣AV| 亚洲国产精品成人久久| 国产成人精品久久亚洲高清不卡 | 久久成人小视频| 久久99亚洲综合精品首页| 无码人妻久久一区二区三区| 精品久久久久久无码人妻蜜桃| 亚洲精品乱码久久久久久按摩 | 久久青青草原精品国产软件| 亚洲精品美女久久久久99| 精品国产青草久久久久福利| www性久久久com| 久久综合给合久久狠狠狠97色69 | 久久久精品波多野结衣| 久久中文骚妇内射| 伊色综合久久之综合久久| 久久狠狠一本精品综合网| 嫩草影院久久国产精品| 色婷婷综合久久久中文字幕| 久久天天躁夜夜躁狠狠躁2022| 久久久久久国产精品美女 | 亚洲欧美成人综合久久久| 久久亚洲中文字幕精品一区| 91精品日韩人妻无码久久不卡| 狠狠色综合网站久久久久久久高清| 精品国产91久久久久久久a| 久久精品国产只有精品2020| 国产精品99久久精品| 久久人人爽人人爽人人片AV不 | 国产三级观看久久| 国产巨作麻豆欧美亚洲综合久久| 久久久青草久久久青草| 国产精品久久久久久福利漫画 | 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 | 久久99精品久久久久久齐齐| 狠狠色丁香婷婷综合久久来来去| 久久伊人精品青青草原高清|