hdu Uncle Tom's Inherited Land*(1*2矩阵覆盖,最大匹配)

来源:互联网 发布:基线网络监控管理系统 编辑:程序博客网 时间:2024/04/29 12:37

http://acm.hdu.edu.cn/showproblem.php?pid=1507


大致题意:在一个n*m的格子上,黑色的地方不可用,问在白色格子上最多可放多少1*2的矩阵。


思路:建图,每个白色格子与它临近的上下左右的白色格子建边,求最大匹配,答案为最大匹配/2,因为是双向图。最后输出匹配边时,当找到一组匹配边记得将该边标记,以防重复计算。


#include <stdio.h>#include <algorithm>#include <set>#include <map>#include <vector>#include <math.h>#include <string.h>#include <queue>#define LL long long#define _LL __int64using namespace std;const int INF = 0x3f3f3f3f;const int mod = 1000000007;const int maxn = 110;int n,m,k;vector <int> edge[maxn];int Map[maxn][maxn];int match[10010],chk[10010];int cnt;int addre[10010];void debug(){for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++)printf("%d%d ",Map[i][j],addre[Map[i][j]]);printf("\n");}}int dfs(int p){    for(int i = 0; i < (int)edge[p].size(); i++)    {        int q = edge[p][i];        if(!chk[q])        {            chk[q] = 1;            if(match[q] == -1 || dfs(match[q]))            {                match[q] = p;                return 1;            }        }    }    return 0;}void output(){int vis[10010];int x,y,xx,yy,tmp;memset(vis,0,sizeof(vis));for(int i = 1; i <= cnt; i++){if(match[i] != -1 && !vis[i]){tmp = match[i];if(!vis[tmp] && i != tmp){vis[i] = 1;vis[tmp] = 1;xx = addre[tmp]/m+1;yy = addre[tmp]%m+1;x = addre[i]/m+1;y = addre[i]%m+1;printf("(%d,%d)--(%d,%d)\n",x,y,xx,yy);}}}}int main(){    int u,v;    while(~scanf("%d %d",&n,&m) && (n || m))    {        for(int i = 1; i <= n*m; i++)            edge[i].clear();        memset(Map,-1,sizeof(Map));        scanf("%d",&k);        for(int i = 0; i < k; i++)        {            scanf("%d %d",&u,&v);            Map[u][v] = 0;        }        cnt = 0;        int tmp = -1;        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= m; j++)            {            tmp++;                if(Map[i][j] < 0)                {                    cnt++;                    addre[cnt] = tmp;                    Map[i][j] = cnt;                }            }        }        //debug();        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= m; j++)            {                if(Map[i][j] == 0) continue;                if(i-1 >= 1 && Map[i-1][j]>0)                    edge[Map[i][j]].push_back(Map[i-1][j]);                if(i+1 <= n && Map[i+1][j]>0)                    edge[Map[i][j]].push_back(Map[i+1][j]);                if(j-1 >= 1 && Map[i][j-1]>0)                    edge[Map[i][j]].push_back(Map[i][j-1]);                if(j+1 <= m && Map[i][j+1]>0)                    edge[Map[i][j]].push_back(Map[i][j+1]);            }        }        memset(match,-1,sizeof(match));        int ans = 0;        for(int i = 1; i <= cnt; i++)        {            memset(chk,0,sizeof(chk));            ans += dfs(i);        }        printf("%d\n",ans/2);output();    }    return 0;}



0 0
原创粉丝点击