二分图:原图G的顶点可以分类两个集合X和Y,所有的边关联的两个顶点恰好一个属于集合X,另一个属于集合Y,则称该图为二分图。
二分图匹配:给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,即一个顶点最多只有一条边。则称M是一个匹配。
二分图最大匹配:图中包含边数最多的匹配称为图的最大匹配。
二分图完美匹配:如果所有点都在匹配边上,则称这个最大匹配是完美匹配。
二分图多重匹配:二分图匹配一对一匹配,这里允许集合Y中的一个元素和集合X中的多个元素匹配(一般有最大限制N),但是集合X中的元素只能和集合Y中的多个元素匹配。
二分图最佳匹配:将二分图加权,在图中找到一个总权值最大的匹配。
二分图最小点覆盖: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。
二分图最小点覆盖 = 二分图最大匹配
二分图最小边覆盖:选择最少的边,使得能够覆盖图中所有的点。
二分图最小边覆盖 = 无向图被重复计算两次,ans = N - 最大匹配数/2
DAG图的最小路径覆盖:用尽量少的不相交简单路径覆盖有向无环图
(DAG)G的所有顶点,这就是DAG图的最小路径覆盖问题。
最小路径覆盖 = 节点数N-最大匹配数
二分图的最大独立集:在N个点的图G中选出若干个点,使这若干个点两两之间没有边,求点数最大值。
二分图的最大独立集数 = 节点数(n)— 最大匹配数(m)
一般是双向边,则被重复计算了两次,ans = N - 最大匹配数/2
二分图最大匹配——匈牙利算法DFS版:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MAXN = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">220</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> Map[MAXN][MAXN]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> bMask[MAXN]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> NX,NY; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> cx[MAXN],cy[MAXN]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> FindPath(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> u) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NY; ++i) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Map[u][i] && !bMask[i]) { bMask[i] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(cy[i] == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> || FindPath(cy[i])) { cy[i] = u; cx[u] = i; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MaxMatch() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> res = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NX; ++i) cx[i] = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NY; ++i) cy[i] = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NX; ++i) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(cx[i] == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= NY; ++j) bMask[j] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; res += FindPath(i); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> res; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回最大匹配数</span> } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>
二分图多重匹配:
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MAXN = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">33</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//最大顶点数</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> Map[MAXN][MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//二分图</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> Mask[MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//寻找增广路径时的标志数组</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> NX,NY,N; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//NX左集合顶点数,NY右集合顶点数</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> vcy[MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//vcy[i]表示右集合i顶点匹配到左集合的顶点数目</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> cy[MAXN][MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//cy[i][j]表示与右集合i顶点匹配的第j个元素</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> limit[MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//每个右集合各顶点最多匹配左集合顶点的个数</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//也可以为limit,表示最多匹配左集合顶点的共同限制数,如果为待求元素,可二分搜索查找答案</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> FindPath(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> u) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//寻找增广路径</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>; ++i) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Map[u][i] && !Mask[i]) { Mask[i] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(vcy[i] < limit[i]) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//vcy[i] < limit</span> { cy[i][vcy[i]++] = u; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; j < vcy[i]; ++j) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//j < vcy[i]</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(FindPath(cy[i][j])) { cy[i][j] = u; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>; } } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> MulMatch() <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//求多重匹配</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> Ans = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(vcy,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(vcy)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= N; ++i) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(Mask,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(Mask)); Ans += FindPath(i); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//计算右边能匹配点个数</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* if(!FindPath(i)) return false; */</span> } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//return true;</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Ans == N) <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"T-shirts rock!\n"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I'd rather not wear a shirt anyway...\n"</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>
二分图最佳匹配——KM算法:
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include<iostream></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include<algorithm></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include<cstdio></span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include<cstring></span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">namespace</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">std</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> MAXN = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">330</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> INF = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0xffffff0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> N,NX,NY; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> link[MAXN],lx[MAXN],ly[MAXN],slack[MAXN]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> visx[MAXN],visy[MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//标记</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> Map[MAXN][MAXN]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//存放权值</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//lx[],ly[]顶标; link[]记录匹配值</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> FindPath(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> u) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//回溯寻找最优解</span> { visx[u] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NY; ++i) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(visy[i]) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">continue</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> temp = lx[u] + ly[i] - Map[u][i]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(temp == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//if(Map[u][i] == lx[u] + ly[i]) //说明是相等子图</span> { visy[i] = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(link[i] == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> || FindPath(link[i])) { link[i] = u; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(slack[i] > temp) slack[i] = temp; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> KM() <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//求权值最大的最佳匹配</span> { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(ly,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(ly)); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(link,-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(link)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NX; ++i) { lx[i] = -INF; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//求最小权匹配则 lx[i] = INF</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= NY; ++j) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Map[i][j] > lx[i]) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//最小权匹配则更改符号</span> lx[i] = Map[i][j]; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NX; ++i) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= NY; ++j) slack[j] = INF; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) { <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(visx,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(visx)); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(visy,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(visy)); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(FindPath(i)) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> d = INF; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= NY; ++j) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(!visy[j] && d > slack[j]) d = slack[j]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(d == INF) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> ; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= NX; ++j) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(visx[j]) lx[j] -= d; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//求最小权值则改为 lx[j] += d;</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= NY; ++j) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(visy[j]) ly[j] += d; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//求最小权值则改为 ly[j] -= d;</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> slack[j] -= d; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> res = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= NY; ++i) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(link[i] > -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) res += Map[link[i]][i]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> res; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//输出最佳匹配的最大权值和</span> } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> main() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> N; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(~<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">scanf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%d"</span>,&N)) { NX = NY = N; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; i <= N; ++i) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> j = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; j <= N; ++j) <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">scanf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%d"</span>,&Map[i][j]); <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">printf</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%d\n"</span>,KM()); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; }</code>