• HDU 2282 Chocolate


    HDU_2228

    这是一个二分图最优匹配的题目,但是一开始不知道怎么去构图,后来看了别人的思路之后不由得觉得构图十分巧妙。

    如果我们要移动巧克力,最后一定是把盒子中多余的巧克力移到空盒子中去,那么我们不妨以多出的每个巧克力以及每个空盒子为研究对象,这样每个巧克力只能放到一个空盒子中,每个空盒子也只能放一个巧克力,于是就可以构成一个二分图去求最优匹配了,其中边权为巧克力和空盒子的最短距离。

    当然为了能应用KM算法,我们在初始化边权的时候可以用MAXD减去最近距离作为边权,之后在统计结果的时候再将其还原即可。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAXD 510
    #define INF 1000000000
    int a[MAXD], r[MAXD];
    int G[MAXD][MAXD], N, nx, ny, yM[MAXD];
    int A[MAXD], B[MAXD], slack;
    int visx[MAXD], visy[MAXD];
    void init()
    {
    int i, j, p;
    ny = 0;
    for(i = 0; i < N; i ++)
    {
    scanf("%d", &a[i]);
    if(!a[i])
    r[ny ++] = i;
    }
    nx = 0;
    for(i = 0; i < N; i ++)
    while(a[i] > 1)
    {
    for(j = 0; j < ny; j ++)
    {
    p = abs(i - r[j]);
    if(N - p < p)
    p = N - p;
    G[nx][j] = MAXD - p;
    }
    a[i] --;
    nx ++;
    }
    }
    int searchpath(int u)
    {
    int v, temp;
    visx[u] = 1;
    for(v = 0; v < ny; v ++)
    if(!visy[v])
    {
    temp = A[u] + B[v] - G[u][v];
    if(temp == 0)
    {
    visy[v] = 1;
    if(yM[v] == -1 || searchpath(yM[v]))
    {
    yM[v] = u;
    return 1;
    }
    }
    else if(temp < slack)
    slack = temp;
    }
    return 0;
    }
    void EK()
    {
    int i, j, u;
    for(i = 0; i < nx; i ++)
    {
    A[i] = 0;
    for(j = 0; j < ny; j ++)
    if(G[i][j] > A[i])
    A[i] = G[i][j];
    }
    memset(B, 0, sizeof(B));
    memset(yM, -1, sizeof(yM));
    for(u = 0; u < nx; u ++)
    for(;;)
    {
    memset(visx, 0, sizeof(visx));
    memset(visy, 0, sizeof(visy));
    slack = INF;
    if(searchpath(u))
    break;
    for(i = 0; i < nx; i ++)
    if(visx[i])
    A[i] -= slack;
    for(i = 0; i < ny; i ++)
    if(visy[i])
    B[i] += slack;
    }
    }
    void printresult()
    {
    int i, res = 0;
    for(i = 0; i < ny; i ++)
    if(yM[i] != -1)
    res += MAXD - G[yM[i]][i];
    printf("%d\n", res);
    }
    int main()
    {
    while(scanf("%d", &N) == 1)
    {
    init();
    EK();
    printresult();
    }
    return 0;
    }


  • 相关阅读:
    jquery中的ajax方法参数的用法和他的含义:
    链接
    数据库视图作用?什么时候用视图?
    八大排序算法的 Python 实现
    @wrap装饰器
    model方法取值总结
    js获取select改变事件
    SQL Server查询时添加一列连续的自增列
    UIAppearance使用详解-备
    NSString、NSData、char* 类型之间的转换-备
  • 原文地址:https://www.cnblogs.com/staginner/p/2199587.html
Copyright © 2020-2023  润新知