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


  • 相关阅读:
    合并2个dll成一个,好处你懂的
    来吧,给你的Winform列表控件画个妆
    DataGridView 的cell赋值没有线程间访问的限制吗?
    设计模式之单例模式
    一个铜钱的故事(转)
    博客美化小结
    FTP操作类(支持异步)
    多线程学习之AsyncOperation实现线程间交互
    消息传递选择:返回值 or 抛出异常
    IIS8.5关于“ 配置错误 不能在此路径中使用此配置节”的解决办法
  • 原文地址:https://www.cnblogs.com/staginner/p/2199405.html
Copyright © 2011-2022 走看看