摘要:
HDU_2228这是一个二分图最优匹配的题目,但是一开始不知道怎么去构图,后来看了别人的思路之后不由得觉得构图十分巧妙。如果我们要移动巧克力,最后一定是把盒子中多余的巧克力移到空盒子中去,那么我们不妨以多出的每个巧克力以及每个空盒子为研究对象,这样每个巧克力只能放到一个空盒子中,每个空盒子也只能放一个巧克力,于是就可以构成一个二分图去求最优匹配了,其中边权为巧克力和空盒子的最短距离。当然为了能应用KM算法,我们在初始化边权的时候可以用MAXD减去最近距离作为边权,之后在统计结果的时候再将其还原即可。#include<stdio.h>#include<string.h># 阅读全文
摘要:
HDU_3395 我们可以把一条鱼拆成两个点分别代表攻击和被攻击,然后按题意对G[i][j]==1的边的权值设为value[i]^ value[j],之后用KM算法求二分图的最优匹配即可。#include<stdio.h>#include<string.h>#define MAXD 110#define INF 1000000000int yM[MAXD], G[MAXD][MAXD], N, value[MAXD];int A[MAXD], B[MAXD];int visx[MAXD], visy[MAXD], slack;char b[MAXD];int init( 阅读全文
摘要:
HDU_3772 我们可以把一个字符串拆成两个点分别代表入度和出度,然后用KM算法去做二分图最优匹配即可。#include<stdio.h>#include<string.h>#define MAXD 210#define INF 1000000000char b[MAXD][1010];int G[MAXD][MAXD] , yM[MAXD], N;int A[MAXD], B[MAXD], slack;int visx[MAXD], visy[MAXD];int check(char *str1, char *str2){ int i, j, num = 0; i 阅读全文
摘要:
HDU_3718我们首先要把字符串中的字符转化成意义相同的[0,k-1]之间的数,然后顺序扫描一遍数组,就可以得到两组数之间的各种匹配的最大值,这样就完成了建图。之后运用KM算法求最优匹配即可。#include<stdio.h>#include<string.h>#define MAXD 30#define MAXN 10010#define INF 1000000000char a[MAXN][5], b[MAXN][5];int visa[MAXN], visb[MAXN], x[MAXN], y[MAXN];int G[MAXD][MAXD], yM[MAXD], 阅读全文
摘要:
HDU_2853我们可以想到,如果我们从头开始匹配,如果最终部分匹配改变之后但没有影响到最终结果的话,那么实际上我们完全没有必要变成新的匹配方式。因而我们考虑为原有的边增加一个“喜好度”,保证其在不影响结果的前提下,会优先匹配原有的边。在处理数据的时候,我们可以把每条边扩大一定的值(我的程序里面是乘以10),然后将原有的边的权值自加1,这样当我们用KM重新进行匹配时,就体现出了优先选已有的边进行匹配,并且这样处理之后并不会影响最优匹配的生成。 最后统计结果的时候,我们对边权进行还原即可,其中更改的数量就是最优匹配中边权模10的结果不为0的边的数量。#include<stdio.h> 阅读全文
摘要:
HDU_2426这个题目是一个求最大权完美匹配的题目,我们需要注意两点:一、要处理好负边的情况。二、要注意N和M不一定相等。对于第一点的处理,我见过的有两种处理方式:①将所有边都初始化成负边,这样当做N-M之间所有的边都是存在的去进行匹配,如果最后发现边权为正的匹配数为N的话就是有解的,否则无解。②将为负值的边视为不存在,并且在KM算法过程中,如果发现当前状态不能再进行增广,则无解。对于第二点的处理,我见过的有些AC的程序也没有注意到这个问题,如果对这一点不加处理的话,如果出现N>M的数据并且是用第①种方式去处理第一点的话,程序会陷入死循环。另外,这个题让我不解的是,现在网上可以搜到的K 阅读全文