zoukankan      html  css  js  c++  java
  • hdu2282:Chocolate(KM匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2282

    Problem Description

    Lethe loves eating chocolates very much. In Lethe's birthday, her good friend echo brings N boxes to her, and makes the boxes on the circle. Furthermore, echo tells Lethe that there are many chocolates in the boxes, but the total number of chocolates doesn't exceed N. Also, echo wants Lethe to displace the chocolates in such a way that in each box remains no more than one chocolate. In one move she can shift one chocolate from current box to its neighboring box. (Each box has two neighboring boxes). Can you tell Lethe the minimum number of move to achieve this goal?

    Input

    There are multi-cases (The total number of cases won't exceed 20). First line is an integer N(1<=N<=500), the total number of boxes. Then N lines follow, each line includes a number, indicates the number of chocolates in the box.

    Output

    Output the minimum number of move.

    Sample Input

    10
    1
    3
    3
    0
    0
    2
    0
    0
    0
    0

    Sample Output

    9

    题意分析:

    有n个盒子,排成环状,里面有若干巧克力,每次可以把一个巧克力移动到相邻的盒子中,要求移动后每个盒子最多只有一个巧克力,求最小的移动次数。

    解题思路:

    移动肯定是要把盒子中巧克力数大于1的移动到空盒子里,

    所以匹配的左边是移动的巧克力,右边是可移动的空盒,权值是移动的最少次数。跑KM匹配即可。

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 550
    int e[N][N], bookx[N], booky[N], lx[N], ly[N], slack[N], march[N], a[N];
    int nx, ny, inf=99999999;
    int dfs(int u)
    {
    	int v, t;
    	bookx[u]=1;
    	for(v=1; v<=ny; v++)
    	{
    		if(booky[v]==0)
    		{
    			t=lx[u]+ly[v]-e[u][v];
    			if(t==0)
    			{
    				booky[v]=1;
    				if(march[v]==0 || dfs(march[v]))
    				{
    					march[v]=u;
    					return 1;
    				}
    			}
    			else
    				slack[v]=min(slack[v], t);
    		}
    	}
    	return 0;
    }
    int KM()
    {
    	int i, j, x, d;
    	memset(ly, 0, sizeof(ly));
    	memset(march, 0, sizeof(march));
    	for(i=1; i<=nx; i++)
    	{
    		lx[i]=-inf;
    		for(j=1; j<=ny; j++)
    			lx[i]=max(lx[i], e[i][j]);
    	}
    	for(x=1; x<=nx; x++)
    	{
    		for(i=1; i<=ny; i++)
    			slack[i]=inf;
    		while(1)
    		{
    			memset(bookx, 0, sizeof(bookx));
    			memset(booky, 0, sizeof(booky));
    			if(dfs(x))
    				break;
    			d=inf;
    			for(i=1; i<=ny; i++)
    				if(!booky[i])
    					d=min(d, slack[i]);
    			for(i=1; i<=nx; i++)
    				if(bookx[i])
    					lx[i]-=d;
    			for(i=1; i<=ny; i++)
    			{
    				if(booky[i])
    					ly[i]+=d;
    				else
    					slack[i]-=d;
    			}
    		}
    	}
    	int sum=0;
    	for(i=1; i<=ny; i++)
    		if(march[i])
    			sum+=e[march[i]][i];		
    	return sum;
    }
    int main()
    {
    	int i, j, n, m; 
    	while(scanf("%d", &n)!=EOF)
    	{
    		nx=0;ny=n;
    		for(i=1; i<=n; i++)
    			scanf("%d", &a[i]);
    		for(i=1; i<=n; i++)
    		{
    			while(a[i]>1)
    			{
    				nx++;
    				a[i]--;
    				for(j=1; j<=n; j++)
    					if(!a[j])
    						e[nx][j]=-min(abs(i-j), n-abs(i-j));
    					else
    						e[nx][j]=-inf;
    			}	
    		}
    		printf("%d
    ", -KM());
    	}
    	return 0;
    }
    
  • 相关阅读:
    【spring cloud】spring cloud zuul 路由网关
    【IDEA】【maven】idea使用maven插件 打包提示找不到符号找不到类,但是却没有错误
    【java】关于Map的排序性的一次使用,有序的Map
    【idea】idea重新打包依赖了父级项目的子级项目,父级项目代码改变,但是子级项目打包依旧是老的代码 问题解决
    【mysql】在mysql中更新字段的部分值,更新某个字符串字段的部分内容
    CentOS RabbitMQ 高可用(Mirrored)
    CentOS MongoDB 高可用实战
    CentOS 安装 gitlab
    SpringBoot打jar包问题
    java中由类名和方法名字符串实现其调用【反射机制】
  • 原文地址:https://www.cnblogs.com/zyq1758043090/p/11852630.html
Copyright © 2011-2022 走看看