hdu1281 棋盘游戏(二分匹配+行列匹配)

来源:互联网 发布:mysql升序和降序 编辑:程序博客网 时间:2024/05/17 02:21

这里写图片描述

两种写法 第一种gg了 不是太理解,以后再来弄懂,以行和列建二分图 左边行右边表示列 求最大二分匹配
重要点求法就是枚举每一个点 判断最大匹配有没有改变

//1#include <string.h>#include <algorithm>#include <iostream>#include <stdio.h>using namespace std;void getmap();int hungarian();bool dfs(int u);int n, m, k;int solve();int maxmatching, imdot = 0;int plan[110][110];int used[110], matching[110], dotx[110110], doty[110110];int main(){    while(scanf("%d%d%d", &n, &m, &k) != EOF)    {        memset(plan, 0, sizeof(plan));        getmap();        maxmatching = hungarian();      //  imdot = solve();        printf("%d %d", maxmatching, imdot);    }}void getmap(){    for(int i = 0; i < k; i++)    {        int x, y;        scanf("%d%d", &x, &y);        plan[x][y] = 1;        dotx[i] = x;        doty[i] = y;    }}int hungarian(){    int ans = 0;    memset(matching, -1, sizeof(matching));    for(int i = 0; i < k; i++)    {        memset(used, 0, sizeof(used));        if(dfs(dotx[i]))            ans++;      //  printf("%d\n", ans);    }    return ans;}bool dfs(int u){    //int v;    for(int i = 0; i < k; i++)    {        if(plan[u][doty[i]]  && !used[doty[i]])        {            printf("%d    %d   %d\n", u, doty[i], matching[doty[i]]);            used[doty[i]] = true;            if(matching[doty[i]] == -1 || dfs(matching[doty[i]]))            {                matching[doty[i]] = u;                return true;            }        }    }    return false;}int solve(){    int ans = 0;    for(int i = 0; i < k; i++)    {        plan[dotx[i]][doty[i]] = 0;        int match1 = hungarian();        if(match1 < maxmatching)            ans++;        plan[dotx[i]][doty[i]] = 1;    }    return ans;}// 2#include <string.h>#include <algorithm>#include <iostream>#include <stdio.h>using namespace std;void getmap();int hungarian();bool dfs(int u);int n, m, k;int solve();int maxmatching, imdot = 0;int plan[110][110];int used[110], matching[110], dotx[110110], doty[110110];int main(){    int cnt = 1;    while(scanf("%d%d%d", &n, &m, &k) != EOF)    {        memset(plan, 0, sizeof(plan));        getmap();        maxmatching = hungarian();        imdot = solve();        printf("Board %d have %d important blanks for %d chessmen.\n",cnt++ , imdot, maxmatching);    }}void getmap(){    for(int i = 0; i < k; i++)    {        int x, y;        scanf("%d%d", &x, &y);        plan[x][y] = 1;        dotx[i] = x;        doty[i] = y;    }}int hungarian(){    int ans = 0;    memset(matching, -1, sizeof(matching));    for(int i = 1; i <= n; i++)    {        memset(used, 0, sizeof(used));        if(dfs(i))            ans++;        //printf("%d\n", ans);    }    return ans;}bool dfs(int u){    //int v;    for(int i = 1; i <= m; i++)    {        if(plan[u][i]  && !used[i])        {           // printf("%d %d %d\n", u, i, matching[i]);            used[i] = true;            if(matching[i] == -1 || dfs(matching[i]))            {                matching[i] = u;                return true;            }        }    }    return false;}int solve(){    int ans = 0;    for(int i = 0; i < k; i++)    {        plan[dotx[i]][doty[i]] = 0;        int match1 = hungarian();        if(match1 < maxmatching)            ans++;        plan[dotx[i]][doty[i]] = 1;    }    return ans;}
0 0