现在的位置: 首页 > 综合 > 正文

hdu 3315 (KM,优先选择原来的匹配)

2018年12月27日 ⁄ 综合 ⁄ 共 1611字 ⁄ 字号 评论关闭

题意很明确,,就是一个二分图,求最优匹配,,蛋疼的是第二个要求,有多少个跟原来的匹配,就是优先选择原来的匹配,跟hdu 2853一样,将边的权值扩大1000倍,原来的匹配边+1,求得的值sum/1000就ok了,原来的匹配个数=sum%1000。。。。用费用流做效果不好,耗时太多






#include<stdio.h>
#include<queue>
#include<string.h>
const int N=110;
const int inf=0x3fffffff;
using namespace std;
int map[N][N],lx[N],ly[N],sx[N],sy[N],d[N],n,match[N],tch[N];
struct node
{
	int w,hp,cut;
}P[100],R[100];

int find(int x)
{
    sx[x]=1;
    for(int i=1;i<=n;i++)
    {
        if(sy[i]==1)continue;
        int temp=lx[x]+ly[i]-map[x][i];
        if(temp==0)
        {
            sy[i]=1;
            if(match[i]==-1||find(match[i])==1)
            {
                match[i]=x;
                return 1;
            }
        }
        else d[i]=d[i]>temp?temp:d[i];
    }
    return 0;
}
int KM()
{
    int i,j,k,min,sum;
    memset(ly,0,sizeof(ly));
    memset(match,-1,sizeof(match));
    for(i=1;i<=n;i++)
    {
        lx[i]=map[i][1];
        for(j=2;j<=n;j++)
            if(lx[i]<map[i][j])
                lx[i]=map[i][j];
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
            d[j]=inf;
        while(1)
        {
            memset(sx,0,sizeof(sx));
            memset(sy,0,sizeof(sy));
            if(find(i)==1)break;
            min=inf;
            for(k=1;k<=n;k++)
                if(sy[k]==0&&min>d[k])
                    min=d[k];
				for(j=1;j<=n;j++)
					if(sx[j]==1)lx[j]-=min;
					for(j=1;j<=n;j++)
						if(sy[j]==1)ly[j]+=min;
        }
    }
    sum=0;
    for(i=1;i<=n;i++)
        sum+=map[match[i]][i];
	if(sum<0)return -1;
    return sum;
}
int main()
{
	int i,j,x,y;
	while(scanf("%d",&n),n)
	{
		for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                map[i][j]=-inf;
		for(i=1;i<=n;i++)
			scanf("%d",&P[i].w);
		for(i=1;i<=n;i++)
			scanf("%d",&P[i].hp);
		for(i=1;i<=n;i++)
			scanf("%d",&R[i].hp);
		for(i=1;i<=n;i++)
			scanf("%d",&P[i].cut);
		for(i=1;i<=n;i++)
			scanf("%d",&R[i].cut);
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				x=P[i].hp/R[j].cut;
				if(P[i].hp%R[j].cut)
					x++;
				if(P[i].cut*x>=R[j].hp)
					map[i][j]=P[i].w*1000;
				else map[i][j]=-P[i].w*1000;
			}
			map[i][i]+=1;
		}
		y=KM();
		if(y==-1)printf("Oh, I lose my dear seaco!\n");
		else printf("%d %.3f%%\n",y/1000,(y%1000)*100.0/n);
		
	}
	return 0;
}


抱歉!评论已关闭.