zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    XP下VS2010 数据库实体模型添加代码项使用 ADO.NET DBContext 添加错误
    URL路径优化
    题解poj2096
    对不起
    TELE poj1155 题解
    在 Linux 上创建第一个 Service Fabric Java 应用程序
    关于日常使用Azure MySQL中遇到的连接问题以及排查方法分享
    在 Azure 中创建静态 HTML Web 应用
    修改Linux时区的2种办法
    怎样在 Azure 应用服务中生成和部署 Java API 应用
  • 原文地址:https://www.cnblogs.com/staginner/p/2199587.html
Copyright © 2011-2022 走看看