zoukankan      html  css  js  c++  java
  • hdu1533解题报告

    题意:这里有一个N*M的方格图.....图中m代表人,H代表房子...并且人数和房子的数量是相等的..那么.每个人可以竖直或者横向走一格,并且花费1S元...那么为了让所有的人进入房子,求解最小的花费

    分析...:这里很明显 ,就是用人去和房子匹配,并且匹配的权值就是花费.就是求解完备最小权值匹配..那么在输入的时候我们记录每一个人和房子的坐标...那么求解所有的人到所有的房子的距离(即是花费),我们取负值然后用KM算法匹配即可得到答案;;

    上马:

    // 15MS 272K 
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    
    #define MAX 101
    #define INF 1<<30-1;
    
    int N,M;
    int man[MAX][2],tol_m;//记录人的坐标和人数
    int house[MAX][2],tol_h;//记录房子坐标和房子数
    int map[MAX][MAX];//map[i][j]表示第i个人到第j个房子的距离(花费)
    int link[MAX],lx[MAX],ly[MAX],slar[MAX];
    bool visx[MAX],visy[MAX];
    
    bool dfs(int x)
    {
    	visx[x]=true;
    	for(int y = 0; y < tol_h; y ++)
    	{
    		if(visy[y]) continue;
    		int t = lx[x] + ly[y] -map[x][y];
    		if(t == 0)
    		{
    			visy[y]=true;
    			if(link[y] == -1 || dfs(link[y]))
    			{
    				link[y]=x;return true;
    			}
    		}
    		else
    			slar[y]=slar[y]>t ? t:slar[y];
    	}
    	return false;
    }
    
    int KM()
    {
    	int i,j;
    	memset(ly,0,sizeof(ly));
    	memset(link,-1,sizeof(link));
    	for( i = 0 ; i < tol_m ; i++)
    	{
    		lx[i]=-INF;
    		for( j = 0 ; j < tol_h ; j++)
    			lx[i]=lx[i]>map[i][j] ? lx[i]:map[i][j];
    	}
    
    	for(int x = 0; x < tol_m ; x ++ )
    	{
    		for(i = 0;i <tol_h; i ++ ) slar[i] = INF;
    		while(1)
    		{
    			memset(visx,false,sizeof(visx));
    			memset(visy,false,sizeof(visy));
    			if(dfs(x)) break;
    
    			int d=INF;
    			for(i = 0 ; i < tol_h; i ++)
    				if(!visy[i])
    					d=d>slar[i] ? slar[i]:d;
    			for(i = 0;i < tol_m; i ++)
    				if(visx[i]) lx[i] -= d;
    			for(i = 0; i< tol_h ; i ++)
    				if(visy[i]) ly[i] +=  d;
    				else  slar[i] -=d;
    		}
    	}
    	int ans=0;
    	for(i = 0;i < tol_h;i ++)
    		if(link[i] != -1) ans+=map[link[i]][i];
    	return ans;
    }
    
    int main()
    {
    	int i,j;
    	char ch[MAX];
    	while(scanf("%d%d",&N,&M),N+M)
    	{
    		tol_m=tol_h=0;
    		for(i=0;i<N;i++)
    		{
    			scanf("%s",ch);
    			for(j=0;j<M;j++)
    			{
    				if(ch[j]=='m')
    					man[tol_m][0]=i,man[tol_m++][1]=j;
    				if(ch[j]=='H')
    					house[tol_h][0]=i,house[tol_h++][1]=j;
    			}
    		}
    		for(i=0;i<tol_m;i++)
    			for(j=0;j<tol_h;j++)
    			{
    				map[i][j]=-(abs(man[i][0]-house[j][0])+abs(man[i][1]-house[j][1]));
    			}
    		printf("%d
    ",-KM());
    	}
    	return 0;
    }

    个人愚昧观点,欢迎指正和讨论

  • 相关阅读:
    函数式宏定义与普通函数
    linux之sort用法
    HDU 4390 Number Sequence 容斥原理
    HDU 4407 Sum 容斥原理
    HDU 4059 The Boss on Mars 容斥原理
    UVA12653 Buses
    UVA 12651 Triangles
    UVA 10892
    HDU 4292 Food
    HDU 4288 Coder
  • 原文地址:https://www.cnblogs.com/pangblog/p/3320259.html
Copyright © 2011-2022 走看看