hdu 2282 Chocolate kuhn_munkras

//拆点,将值为m的a点拆成m个值为1的点,将m-1个点与除a点以外的值为0的点建立关系。建立矩阵mat[ind][n]
//即求选择ind个数,使得这ind个数,不同行不同列,使得它们的和最小 即kuhn_munkras

#include <iostream>
#include <cstring>
#include <cmath>
using namespace
std;

#define MAXN 500
#define inf 1000000000
#define _clr(x) memset(x,0xff,sizeof(int)*n)
int match1[MAXN], match2[MAXN];
int
m, n, mat[MAXN][MAXN];

int
kuhn_munkras()
{

    int
s[MAXN],t[MAXN],l1[MAXN],l2[MAXN],p,q,ret=0,i,j,k;
    for
(i=0;i<m;i++)
        for
(l1[i]=-inf,j=0;j<n;j++)
            l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];
    for
(i=0;i<n;l2[i++]=0);
    for
(_clr(match1),_clr(match2),i=0;i<m;i++){
        for
(_clr(t),s[p=q=0]=i;p<=q&&match1[i]<0;p++)
            for
(k=s[p],j=0;j<n&&match1[i]<0;j++)
                if
(l1[k]+l2[j]==mat[k][j]&&t[j]<0){
                    s[++q]=match2[j],t[j]=k;
                    if
(s[q]<0)
                        for
(p=j;p>=0;j=p)
                            match2[j]=k=t[j],p=match1[k],match1[k]=j;
                }

        if
(match1[i]<0){
            for
(i--,p=inf,k=0;k<=q;k++)
                for
(j=0;j<n;j++)
                    if
(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)
                        p=l1[s[k]]+l2[j]-mat[s[k]][j];
            for
(j=0;j<n;l2[j]+=t[j]<0?0:p,j++);
            for
(k=0;k<=q;l1[s[k++]]-=p);
        }
    }

    for
(i=0;i<m;i++)
        ret+=mat[i][match1[i]];
    return
ret;
}


int
main()
{

    while
(scanf("%d", &n) != EOF)
    {

        int
i, j, a[MAXN], k;
        for
(i = 0; i < n; ++i)
        {

            for
(j = 0; j < n; ++j)
            {

                mat[i][j] = -1000000;
            }
        }

        for
(i = 0; i < n; ++i)
        {

            scanf("%d", &a[i]);
        }

        int
ind = 0;
        for
(i = 0; i < n; ++i)
        {
   
            for
(k = 0; k < a[i]-1; ++k)
            {

                for
(j = 0; j < n; ++j)
                {

                    if
(!a[j])
                    {

                        mat[ind][j] = abs(j-i) > n/2 ? -(n-abs(j-i)) : -abs(j-i);
                    }
                }

                ind++;
            }   
        }

        m = ind;
        printf("%d\n", -kuhn_munkras());
    }

    return
0;
}

posted on 2010-01-24 10:53  ZAFU_VA  阅读(228)  评论(0编辑  收藏  举报

导航