• <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ǎ崽 閱讀(1745) 評論(2)  編輯 收藏 引用

            評論:
            # re: 二分圖的完美匹配 2009-04-24 18:48 | wswyb001
            好長啊,還沒有學KM  回復  更多評論
              
            # re: 二分圖的完美匹配 2009-04-28 14:42 | shǎ崽
            @wswyb001
            這個是n^4的算法
            浙大模板n^3的,現在用那個。。。  回復  更多評論
              
            久久乐国产综合亚洲精品| 久久电影网一区| 久久99热这里只有精品国产 | 久久电影网| 久久噜噜电影你懂的| 久久精品中文闷骚内射| 蜜臀久久99精品久久久久久小说 | 国产69精品久久久久99尤物| 97久久精品无码一区二区天美| 久久夜色精品国产网站| 日韩精品无码久久久久久| 久久亚洲私人国产精品| 久久人人爽人人爽人人片AV不| 99久久精品国产一区二区 | 香蕉99久久国产综合精品宅男自| 久久人人爽人人爽人人片AV麻豆| 久久国产成人午夜aⅴ影院| 一级女性全黄久久生活片免费| 怡红院日本一道日本久久| 久久久久国产亚洲AV麻豆| 亚洲欧美国产精品专区久久| 久久WWW免费人成一看片| 99久久国语露脸精品国产| 国产L精品国产亚洲区久久| 久久久精品国产亚洲成人满18免费网站 | 97热久久免费频精品99| 免费国产99久久久香蕉| 欧美一级久久久久久久大| 久久99精品久久久大学生| 99久久免费国产精精品| 日批日出水久久亚洲精品tv| 久久久久久毛片免费播放| 国产成人香蕉久久久久| 国产激情久久久久久熟女老人 | 久久久无码精品亚洲日韩京东传媒 | 久久乐国产综合亚洲精品| 国内精品久久久久久99| 无码任你躁久久久久久| 国产精品欧美久久久天天影视| 无码任你躁久久久久久久| 2022年国产精品久久久久|