• 二分图匹配(KM算法)n^3 分类: ACM TYPE 2014-10-01 21:46 98人阅读 评论(0) 收藏


    #include <iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    const int maxn = 301;
    const int INF = (1<<31)-1;
    int w[maxn][maxn];
    int lx[maxn],ly[maxn]; //顶标
    
    int linky[maxn];
    
    int visx[maxn],visy[maxn];
    int slack[maxn];
    int n;
    bool find(int x)
    {
        visx[x] = true;
        for(int y = 1; y <=n; y++)
        {
            if(visy[y])   continue;
            int t = lx[x] + ly[y] - w[x][y];
            if(t==0)
            {
                visy[y] = true;
                if(linky[y] == -1 || find(linky[y]))
                {
                    linky[y] = x;
                    return true;        
                }
            }
            else if(slack[y] > t)      slack[y] = t;
        }
        return false;                   
    }
    
    int KM()                
    {
        int i,j;
    
        memset(linky,-1,sizeof(linky));
        memset(ly,0,sizeof(ly));
        
        for(i = 1; i <=n; i++)			//初始化顶标 
        {
             lx[i] = -INF;
             for(j = 1; j <=n; j++)
             {
                if(w[i][j] > lx[i])   lx[i] = w[i][j];         	
             }
        }
    
        for(int x = 1; x <=n; x++)
        {
            for(i = 1; i <=n; i++) 	slack[i] = INF;
            while(true)
            {
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                if(find(x))  break;
                int d = INF;
                
                for(i = 1; i <=n; i++)          
                {
                    if(!visy[i] && d > slack[i])    d = slack[i];
                }
                for(i = 1; i <=n; i++)
                {
                    if(visx[i])    lx[i] -= d;
                }
                for(i = 1; i <=n; i++)
                {
                    if(visy[i])	   ly[i] += d;
                    else           slack[i] -= d;
                }
            }
        }
        
        int result = 0;
        for(i = 1; i <=n; i++)
        {
    	    if(linky[i]>-1)
    	    {
    	        result += w[linky[i]][i];    	    	
    	    }
        }
    
        return result;
    }
    
    int main()
    {
    
        while(scanf("%d",&n)==1)
        {
            int cost;
            for(int i=1;i<=n;i++)
            {
    	        for(int j=1;j<=n;j++)
    	        {
    	            scanf("%d",&cost);
    	            w[i][j] = cost;
    	        }        	
            }
            printf("%d
    ",KM());
        }
        return 0;
    }
    更新顶标的问题的了

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    mysql字符集
    zabbix自动发现zabbix_agent后添加到所属组和链接到某些模块(九)
    zabbix_agent添加到系统服务启动(八)
    苦苦的追寻,奈何~~(一年三份工作的总结)
    systemd service 设置limit,不生效问题
    logrotate
    cron定时任务
    crontab定时任务第一个周期未完成下一个周期执行就来了
    来年仍旧迷茫...
    rsync的daemon模式
  • 原文地址:https://www.cnblogs.com/you-well-day-fine/p/4671619.html
Copyright © 2020-2023  润新知