二分图【模板】

二分图:原图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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值