• pku2195 Going Home(最大匹配模板)


    模板题来的,构完图之后就是直接的模板了,可惜对于这个算法还是了解的不够深…………

    若求得的是最大匹配,则将权值为正,若为最小匹配,则将权值该为相反数

    此模板默认所有数组默认下标从1 开始,复杂度O(n^3)
    mat 表示邻接矩阵,nx,ny表示二分的大小

    lx,ly表示为顶标,fx[i],fy[i]标记十分访问过该点

    mx[i],my[i] 表示匹配

    先贴模板:

    KM算法模板
    #include <iostream>

    using namespace std;

    const int MAXN = 110;
    const int INF = 0x7FFFFFFF;

    int nx, ny, w[MAXN][MAXN], lx[MAXN], ly[MAXN];
    int fx[MAXN], fy[MAXN], matx[MAXN], maty[MAXN];

    int path(int u)
    {
    fx[u]
    = 1;
    for (int v = 1; v <= ny; v++) if (lx[u] + ly[v] == w[u][v] && fy[v] < 0)
    {
    fy[v]
    = 1;
    if (maty[v] < 0 || path(maty[v]))
    {
    matx[u]
    = v;
    maty[v]
    = u;
    return 1;
    }
    }
    return 0;
    }

    int perfect_match()
    {
    int ret = 0;
    memset(ly,
    0, sizeof(ly));
    for (int i = 1; i <= nx; i++)
    {
    lx[i]
    = -INF;
    for (int j = 1; j <= ny; j++) if (w[i][j] > lx[i]) lx[i] = w[i][j];
    }
    memset(matx,
    -1, sizeof(matx));
    memset(maty,
    -1, sizeof(maty));
    for (int i = 1; i <= nx; i++)
    {
    memset(fx,
    -1, sizeof(fx));
    memset(fy,
    -1, sizeof(fy));
    if (!path(i))
    {
    i
    --;
    int p = INF;
    for (int k = 1; k <= nx; k++) if (fx[k] > 0)
    for (int j = 1; j <= ny; j++) if (fy[j] < 0 && lx[k] + ly[j] - w[k][j] < p)
    p
    =lx[k]+ly[j]-w[k][j];
    for (int j = 1; j <= ny; j++) ly[j] += fy[j]<0 ? 0 : p;
    for (int j = 1; j <= nx; j++) lx[j] -= fx[j]<0 ? 0 : p;
    }
    }
    //for (int i = 1; i <= ny; i++) ret += w[maty[i]][i];
    for (int i = 1; i <= ny; i++)
    if (maty[i]!=-1) ret += w[maty[i]][i];

    return ret;
    }

    pku 2195

    View Code
    #include<iostream>
    #define inf 100000000
    using namespace std;
    int mx[110],my[110],mat[110][110],n,fx[110],fy[110],lx[110],ly[110];
    struct house
    {
    int x,y;
    }h[
    110];
    struct people
    {
    int x,y;
    }p[
    110];
    inline
    int dis(int i,int j)
    {
    return abs(h[j].x-p[i].x)+abs(h[j].y-p[i].y);
    }
    int path(int u)
    {
    fx[u]
    = 1;
    for (int v = 1; v <= n; v++) if (lx[u] + ly[v] == mat[u][v] && fy[v] < 0)
    {
    fy[v]
    = 1;
    if (my[v] < 0 || path(my[v]))
    {
    mx[u]
    = v;
    my[v]
    = u;
    return 1;
    }
    }
    return 0;
    }

    int perfect_match()
    {
    int ret = 0;
    memset(ly,
    0, sizeof(ly));
    for (int i = 1; i <= n; i++)
    {
    lx[i]
    = -inf;
    for (int j = 1; j <= n; j++) if (mat[i][j] > lx[i]) lx[i] = mat[i][j];
    }
    memset(mx,
    -1, sizeof(mx));
    memset(my,
    -1, sizeof(my));
    for (int i = 1; i <= n; i++)
    {
    memset(fx,
    -1, sizeof(fx));
    memset(fy,
    -1, sizeof(fy));
    if (!path(i))
    {
    i
    --;
    int p = inf;
    for (int k = 1; k <= n; k++) if (fx[k] > 0)
    for (int j = 1; j <= n; j++) if (fy[j] < 0 && lx[k] + ly[j] - mat[k][j] < p)
    p
    =lx[k]+ly[j]-mat[k][j];
    for (int j = 1; j <= n; j++) ly[j] += fy[j]<0 ? 0 : p;
    for (int j = 1; j <= n; j++) lx[j] -= fx[j]<0 ? 0 : p;
    }
    }
    for (int i = 1; i <= n; i++)
    ret
    += mat[my[i]][i];

    return ret;
    }

    int main()
    {
    int n1,m1;
    char a;
    while(scanf("%d %d",&n1,&m1)==2&&(n1||m1))
    {
    int count1=0,count2=0;
    for(int i=1;i<=n1;i++)
    {
    getchar();
    for(int j=1;j<=m1;j++)
    {
    scanf(
    "%c",&a);
    if(a=='H') h[++count1].x=i,h[count1].y=j;
    if(a=='m') p[++count2].x=i,p[count2].y=j;
    }
    }
    for(int i=0;i<110;i++)
    for(int j=0;j<110;j++)
    mat[i][j]
    =-inf;
    for(int i=1;i<=count2;i++)
    for(int j=1;j<=count1;j++)
    mat[i][j]
    =-dis(i,j);
    n
    =count1;
    printf(
    "%d\n",-perfect_match());
    }
    return 0;
    }
  • 相关阅读:
    react-webpack-express
    React总结和遇到的坑
    vue+node+mongodb实现的功能
    webpack整体了解
    webpack踩坑
    深入了解MongoDB
    实现pdf word在线浏览和下载
    node实现爬虫
    火客声音分析
    抖音二婷衣橱分析
  • 原文地址:https://www.cnblogs.com/nanke/p/2165900.html
Copyright © 2020-2023  润新知