hdu 2255 奔小康赚大钱 KM算法 模板题

这是复杂度为O(n^4)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;

const int N = 300 + 11 ;

struct Graph {
    int from[N] ;//记录匹配状态
    int w[N][N] ;//边权
    int lx[N] ,ly[N] ;//点标
    bool sx[N] , sy[N] ;
    int nx , ny ;//nx左节点的个数,ny右节点的个数

    bool match(int u) {
        sx[u] = true ;
        for(int i = 1; i <= ny ; ++i) {
            if(!sy[i] && lx[u] + ly[i] == w[u][i]) {
                sy[i] = true ;
                if(from[i] ==  -1 || match(from[i])) {//无数次写成match(i),,,,注意了
                    from[i] = u ;
                    return true ;
                }
            }
        }
        return false ;
    }

    void std_fun() {
        memset(lx , 0 , sizeof(lx)) ;
        memset(ly , 0 , sizeof(ly)) ;
        for(int i = 1; i <= nx ;++i) {
            for(int j= 1; j <= ny; ++j) {
                scanf("%d",&w[i][j]);
                lx[i] = max(lx[i] , w[i][j]) ;
            }
        }
        memset(from , -1 , sizeof(from)) ;
        for(int k = 1; k <= nx; ++k) {
            while(true) {
                memset(sx , 0 , sizeof(sx)) ;
                memset(sy , 0 , sizeof(sy)) ;
                if(match(k)) break ;
                int d = (1<<30)-1+(1<<30) ;
                for(int i = 1 ; i <= nx ; ++i) {
                    if(sx[i]) {
                        for(int j = 1; j <= ny ; ++j) {
                            if(!sy[j]) {//这里是非,,,,
                                d = min(d , lx[i] + ly[j] - w[i][j]) ;
                            }
                        }
                    }
                }
                for(int i = 1; i <= nx; ++i) {
                    if(sx[i]) lx[i] -= d ;
                }
                for(int i = 1; i <= ny ; ++i){
                    if(sy[i]) ly[i] += d ;
                }
            }
        }
        int sum = 0 ;
        for(int i = 1; i <= ny ; ++i) {
            if(from[i] != -1) sum += w[from[i]][i] ;
        }
        printf("%d\n",sum) ;
    }
}g ;

int main() {
    int n;
    while(scanf("%d",&n)==1) {
        g.nx = g.ny = n ;
        g.std_fun() ;
    }
}

复杂度为O(n^3) :但比上面的只快了100多ms

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;

const int N = 300 + 11 ;

struct Graph {
	int w[N][N] ;
	int lx[N] , ly[N] ;
	int from[N] , slack[N] ;//右节点匹配状态,,记录点的权值差
	bool sx[N] , sy[N] ;
	int nx , ny ;//左右节点数

	void std_fun() {
		memset(lx , 0 , sizeof(lx)) ;
		memset(ly , 0 , sizeof(ly)) ;
		for(int i = 1; i <= nx ;++i) {
			for(int j = 1; j <= ny ;++j) {
				scanf("%d",&w[i][j]) ;
				if(w[i][j] > lx[i]) lx[i] = w[i][j] ;
			}
		}
		memset(from , -1 ,sizeof(from)) ;
		for(int i = 1; i <= nx ; ++i) {
            memset(slack , (1<<6) , sizeof(slack)) ;
			while(true) {
				memset(sx , 0 , sizeof(sx)) ;
				memset(sy , 0 , sizeof(sy)) ;
				if(match(i)) break ;
				int d = (1<<30) ;
				for(int i = 1; i <= ny ; ++i) {
					if(!sy[i] && slack[i] < d) d = slack[i] ;
				}
				for(int i = 1; i <= nx ; ++i) {
					if(sx[i]) lx[i] -= d ;
				}
				for(int i = 1; i <= ny ; ++i) {
					if(sy[i]) ly[i] += d ;
					//else slack[i] -= d ;//这句应该可以不要,但大神的模板这里有,,,
				}
			}
		}
		int sum = 0 ;
		for(int i = 1; i <= ny ; ++i) {
			if(from[i] != -1) sum += w[from[i]][i] ;
		}
		printf("%d\n" , sum) ;
	}

	bool match(int u) {
		sx[u] = true ;
		for(int i = 1; i <= ny ; ++i) {
            if(sy[i]) continue ;
			int tmp = lx[u] + ly[i] - w[u][i] ;
			if(tmp == 0) {
				sy[i] = true ;
				if(from[i] == -1 || match(from[i])) {
					from[i] = u ;
					return true ;
				}
			}else {
				if(slack[i] > tmp) slack[i] = tmp ;
			}
		}
		return false ;
	}
}g ;

int main() {
	int n ;
	while(scanf("%d",&n)==1) {
		g.nx = g.ny = n ;
		g.std_fun() ;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动控制节水灌溉技术的高低代表着农业现代化的发展状况,灌溉系统自动化水平较低是制约我国高效农业发展的主要原因。本文就此问研究了单片机控制的滴灌节水灌溉系统,该系统可对不同土壤的湿度进行监控,并按照作物对土壤湿度的要求进行适时、适量灌水,其核心是单片机和PC机构成的控制部分,主要对土壤湿度与灌水量之间的关系、灌溉控制技术及设备系统的硬件、软件编程各个部分进行了深入的研究。 单片机控制部分采用上下位机的形式。下位机硬件部分选用AT89C51单片机为核心,主要由土壤湿度传感器,信号处理电路,显示电路,输出控制电路,故障报警电路等组成,软件选用汇编语言编程。上位机选用586型以上PC机,通过MAX232芯片实现同下位机的电平转换功能,上下位机之间通过串行通信方式进行数据的双向传输,软件选用VB高级编程语言以建立友好的人机界面。系统主要具有以下功能:可在PC机提供的人机对话界面上设置作物要求的土壤湿度相关参数;单片机可将土壤湿度传感器检测到的土壤湿度模拟量转换成数字量,显示于LED显示器上,同时单片机可采用串行通信方式将此湿度值传输到PC机上;PC机通过其内设程序计算出所需的灌水量和灌水时间,且显示于界面上,并将有关的灌水信息反馈给单片机,若需灌水,则单片机系统启动鸣音报警,发出灌水信号,并经放大驱动设备,开启电磁阀进行倒计时定时灌水,若不需灌水,即PC机上显示的灌水量和灌水时间均为0,系统不进行灌水。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值