zoukankan      html  css  js  c++  java
  • 匈牙利算法--java

    先上例题

    杭电acm 2063 :http://acm.hdu.edu.cn/showproblem.php?pid=2063

    bool 寻找从k出发的对应项出的可增广路
    
    {
        while (从邻接表中列举k能关联到顶点j)
        {
            if (j不在增广路上)
            {
                把j加入增广路;
                if (j是未盖点 或者 从j的对应项出发有可增广路)
                {
                    修改j的对应项为k;
                    则从k的对应项出有可增广路,返回true;
                }
            }
        }
        则从k的对应项出没有可增广路,返回false;
    }
    void 匈牙利hungary()
    {
        for i->1 to n
        {
            if (则从i的对应项出有可增广路)
               匹配数++;
        }
        输出 匹配数;
    }

    附上题解代码

    import java.util.*;
    
    
    public class Main {
        
            public int map[][]=new int [1010][1010];//男生和女的有关系数
            public int match[]=new int[1010];        //是否已经匹配数
            public int used[]=new int [1010];        //是否有关系
            public boolean find(int x,int n ){
                for(int i=1;i<=n;i++){
                if(used[i]==0&&map[x][i]==1){            //如果没有i男生是空闲的且x,i有关系
                    
                    used[i]=1;                            
                    if(match[i]==-1||find(match[i],n)){    //如果i男生没有匹配或者她放弃男生i并且另外找到了自己的伴
                        match[i]=x;
                        return true;
                    }
                }    
                
                }return false;
                }                //该函数判断女生爱能不能找到伴
    
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            int k,m,n;
            while(sc.hasNext()){
                k=sc.nextInt();
                if(k==0)
                    System.exit(0);
                m=sc.nextInt();
                n=sc.nextInt();
                int cnt=0;
            Main lei=new Main();
            Arrays.fill(lei.match,-1);
            for(int i=0;i<lei.map.length;i++){
                for(int j=0;j<lei.map.length;j++){
                    lei.map[i][j]=0;
                }
            }
            for(int i=1;i<=k;i++){
                int a,b;
                a=sc.nextInt();
                b=sc.nextInt();
                lei.map[a][b]=1;
            }
            for(int i=1;i<=m;i++){
                Arrays.fill(lei.used,0);
                if(lei.find(i,n))
                    cnt++;
            }
            System.out.println(cnt);
        }
    }
    }

    匈牙利算法精髓就是尽可能的多占,可以通过回溯来试,不过当试的时候破坏了之前的安排,则是无能为力的,只能要求尽可能的多。

    杭电3020

    package demo2;
     
    import java.util.*;
     
     
    public class Main6 {
         static int edge[][]=new int [1005][1005];
         
         static int num_map[][]=new int [1000][1001];
         static char map[][]=new char[1000][1001];
         static int cx[]=new int[505];
         static int cy[]=new int[505];
         static int vis[]=new int[505];
         static int match[]=new int[505];
         static int N,K,M;
         static int d[][]={{-1,0},{1,0},{0,-1},{0,1}};
         public static int path(int u){
             int v;
             for(v=1;v<=M;v++){
                 if(vis[v]==0&&edge[u][v]==1){
                     vis[v]=1;
                     if(match[v]==-1||path(match[v])==1){
                         match[v]=u;
                         return 1;
                     }
                 }
             }
             return 0;
         }
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
             N = sc.nextInt();
            
             while(N-->0){
                 int count=0;
                 for(int i=0;i<num_map.length;i++)
                     Arrays.fill(num_map[i], 0);
                 for(int i=0;i<edge.length;i++)
                     Arrays.fill(edge[i], 0);
                 
                 int m= sc.nextInt();
                 int k = sc.nextInt();
                 sc.nextLine();
                 for(int i=0;i<m;i++){
                      String s = sc.nextLine();
                      map[i]=s.toCharArray();
                       
                 }
                 
    //             int res=0;
                 int num=0;
                 for(int i=0;i<m;i++){
                     for(int j=0;j<k;j++){
    //                     System.out.print([i][j]);
                         if(map[i][j]=='*'){
                             num_map[i][j]=++num;
                             
    //                         System.out.println(num_map[i][j]);
                         }
                     }
    //                 System.out.println();
                     }
                K=num;M=num;
                System.out.println(num);
                for(int i=0;i<m;i++){
                    for(int j=0;j<k;j++){
                        if(num_map[i][j]!=0){
    //                        System.out.println(num_map[i][j]);
                            for(int c=0;c<4;c++){
                                int x = i+d[c][0];
                                int y = j+d[c][1];
                                if(x<0||y<0||x>=m||y>=k)
                                    continue;
                                if(num_map[x][y]!=0)
                                    edge[num_map[i][j]][num_map[x][y]]=1;
                                
                            }
                        }
                    }
                }
    //            for(int i=1;i<=m;i++){
    //                for(int j=1;j<=k;j++){
    //                    System.out.print(num_map[i][j]);
    //                }
    //                System.out.println();
    //            }
                Arrays.fill(match, -1);
                for(int i=1;i<=K;i++){
                    Arrays.fill(vis, 0);
                    if(path(i)==1)
                        count++;
                }
                System.out.println(num-count/2);
             }
    }
    }
  • 相关阅读:
    2016"百度之星"
    codeforces 55 div2 C.Title 模拟
    codeforces 98 div2 C.History 水题
    codeforces 97 div2 C.Replacement 水题
    codeforces 200 div2 C. Rational Resistance 思路题
    bzoj 2226 LCMSum 欧拉函数
    hdu 1163 九余数定理
    51nod 1225 余数的和 数学
    bzoj 2818 gcd 线性欧拉函数
    Codeforces Round #332 (Div. 2)D. Spongebob and Squares 数学
  • 原文地址:https://www.cnblogs.com/ls-pankong/p/9781296.html
Copyright © 2011-2022 走看看