• HDU 3718 Similarity


    HDU_3718

    我们首先要把字符串中的字符转化成意义相同的[0,k-1]之间的数,然后顺序扫描一遍数组,就可以得到两组数之间的各种匹配的最大值,这样就完成了建图。

    之后运用KM算法求最优匹配即可。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 30
    #define MAXN 10010
    #define INF 1000000000
    char a[MAXN][5], b[MAXN][5];
    int visa[MAXN], visb[MAXN], x[MAXN], y[MAXN];
    int G[MAXD][MAXD], yM[MAXD], N, K, M;
    int A[MAXD], B[MAXD], slack;
    int visx[MAXD], visy[MAXD];
    void init()
    {
    int i, j, k;
    for(i = 0; i < N; i ++)
    scanf("%s", a[i]);
    memset(visa, 0, sizeof(visa));
    k = 0;
    for(i = 0; i < N; i ++)
    if(!visa[i])
    {
    for(j = i; j < N; j ++)
    if(a[j][0] == a[i][0])
    {
    visa[j] = 1;
    x[j] = k;
    }
    k ++;
    }
    }
    void initM()
    {
    int i, j, k;
    for(i = 0; i < N; i ++)
    scanf("%s", b[i]);
    memset(visb, 0, sizeof(visb));
    k = 0;
    for(i = 0; i < N; i ++)
    if(!visb[i])
    {
    for(j = i; j < N ; j ++)
    if(b[j][0] == b[i][0])
    {
    visb[j] = 1;
    y[j] = k;
    }
    k ++;
    }
    memset(G, 0, sizeof(G));
    for(i = 0; i < N; i ++)
    G[x[i]][y[i]] ++;
    }
    int searchpath(int u)
    {
    int v, temp;
    visx[u] = 1;
    for(v = 0; v < K; 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 KM()
    {
    int i, j, u;
    for(i = 0; i < K; i ++)
    {
    A[i] = 0;
    for(j = 0; j < K; 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 < K; u ++)
    for(;;)
    {
    memset(visx, 0, sizeof(visx));
    memset(visy, 0, sizeof(visy));
    slack = INF;
    if(searchpath(u))
    break;
    for(i = 0; i < K; i ++)
    {
    if(visx[i])
    A[i] -= slack;
    if(visy[i])
    B[i] += slack;
    }
    }
    }
    void printresult()
    {
    int i, res =0;
    for(i = 0 ; i < K; i ++)
    res += G[yM[i]][i];
    printf("%.4f\n", (double)res / N);
    }
    int main()
    {
    int i, T;
    scanf("%d", &T);
    while(T --)
    {
    scanf("%d%d%d", &N, &K, &M);
    init();
    for(i = 0; i < M; i ++)
    {
    initM();
    KM();
    printresult();
    }
    }
    return 0;
    }


  • 相关阅读:
    【UOJ #46】 【清华集训2014】玄学
    【BZOJ3626】 [LNOI2014]LCA
    THUSC 2017 游记
    Cqoi2017试题泛做
    全国高校程序设计大赛 评定奖学金
    全国高校程序设计大赛 素数和偶数
    全国高校程序设计大赛 八进制数中含7的总个数
    全国高校程序设计大赛 电商促销
    PTA 02-线性结构1 两个有序链表序列的合并
    PTA 02-线性结构2 一元多项式的乘法与加法运算
  • 原文地址:https://www.cnblogs.com/staginner/p/2199405.html
Copyright © 2020-2023  润新知