最优匹配

最小权匹配:

#include <iostream>
#include <cstdio>
#include <cstring>
usingnamespace std;

constint N =210;
constint M =30100;
constint inf =0x1fffffff;

int n, m, tot, lx[N], ly[N], match[N], h[N], v[M], w[M], nxt[M];
bool visx[N], visy[N];
int lack;

void add(int a, int b, int c)
{
    v[tot] = b;
    w[tot] = c;
    nxt[tot] = h[a];
    h[a] = tot++;
}

bool find(int u)
{
    int i, t;
    visx[u] =true;
    for(i = h[u]; i !=-1; i = nxt[i])
        if(!visy[v[i]])
        {
            t = w[i] - lx[u] - ly[v[i]];
            if(t ==0)
            {
                visy[v[i]] =true;
                if(match[v[i]]==-1|| find(match[v[i]]))
                {
                    match[v[i]] = u;
                    returntrue;
                }
            }
            elseif(t >0)
                lack = min(lack, t);
        }
    returnfalse;
}

int main()
{
    int t, a, b, c, i, j, ans;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d", &n, &m);
        tot =0;
        memset(h, -1, sizeof(h));
        for(i =0; i < m; i++)
        {
            scanf("%d%d%d", &a, &b, &c);
            add(a, b, c);
        }
        for(i =1; i <= n; i++)
        {
            lx[i] = inf;
            ly[i] =0;
            for(j = h[i]; j !=-1; j = nxt[j])
                lx[i] = min(lx[i], w[j]);
        }
        memset(match, -1, sizeof(match));
        for(i =1; i <= n; i++)
        {
            memset(visx, false, sizeof(visx));
            memset(visy, false, sizeof(visy));
            lack = inf;
            while(!find(i))
            {
                for(j =1; j <= n; j++)
                {
                    if(visx[j])  lx[j] += lack;
                    if(visy[j])  ly[j] -= lack;
                }
                memset(visx, false, sizeof(visx));
                memset(visy, false, sizeof(visy));
            }
        }
        ans =0;
        for(i =1; i <= n; i++)  ans = ans + lx[i] + ly[i];
        printf("%d\n", ans);
    }
    return  0;
}

 

最大权匹配:

#include <iostream>
#include <cstdio>
#include <cstring>
usingnamespace std;

constint N =310;
constint inf =0x1fffffff;

int n, lx[N], ly[N], match[N], w[N][N];
bool visx[N], visy[N];
int lack;

int getNum()
{
    char c;
    int ans =0;
    c = getchar();
    while(c<'0'|| c>'9') c = getchar();
    while(c>='0'&& c<='9')
    {
        ans = ans*10+c-'0';
        c = getchar();
    }
    return  ans;
}

bool find(int u)
{
    int i, t;
    visx[u] =true;
    for(i =1; i <= n; i++)
        if(!visy[i])
        {
            t = lx[u] + ly[i] - w[u][i];
            if(t ==0)
            {
                visy[i] =true;
                if(match[i]==-1|| find(match[i]))
                {
                    match[i] = u;
                    returntrue;
                }
            }
            elseif(t >0)
                lack = min(lack, t);
        }
    returnfalse;
}

int main()
{
    int i, j, ans;
    while(scanf("%d", &n) != EOF)
    {
        for(i =1; i <= n; i++)
        {
            lx[i] = ly[i] =0;
            for(j =1; j <= n; j++)
            {
                w[i][j] = getNum();
                lx[i] = max(lx[i], w[i][j]);
            }
        }
        memset(match, -1, sizeof(match));
        for(i =1; i <= n; i++)
        {
            memset(visx, false, sizeof(visx));
            memset(visy, false, sizeof(visy));
            lack = inf;
            while(!find(i))
            {
                for(j =1; j <= n; j++)
                {
                    if(visx[j])  lx[j] -= lack;
                    if(visy[j])  ly[j] += lack;
                }
                memset(visx, false, sizeof(visx));
                memset(visy, false, sizeof(visy));
            }
        }
        ans =0;
        for(i =1; i <= n; i++)  ans = ans + lx[i] + ly[i];
        printf("%d\n", ans);
    }
    return0;
}
posted @ 2012-09-23 20:06  fCarver7  阅读(129)  评论(0编辑  收藏  举报