• 匈牙利算法--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);
             }
    }
    }
  • 相关阅读:
    java的初始化
    java继承
    java多态
    static、final关键字
    java的清理
    java访问权限控制
    java对象与引用及参数传递
    java学习--学生成绩管理系统
    The Nth Item 南昌网络赛(递推数列,分段打表)
    Random Access Iterator 徐州网络赛(树形dp)
  • 原文地址:https://www.cnblogs.com/ls-pankong/p/9781296.html
Copyright © 2020-2023  润新知