hdu 1507 Uncle Tom's Inherited Land* 最大匹配

来源:互联网 发布:羊绒围巾 牌子 知乎 编辑:程序博客网 时间:2024/05/16 08:12
#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <algorithm>#include <iostream>using namespace std;const int maxn=10010;const int maxc=110;vector<int>e[maxn];int map[maxc][maxc];int vis[maxn],pre[maxn];int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};int find(int u)//判断增广路是否存在,匈牙利算法{    int i,j,v;    for(i=0;i<e[u].size();i++)    {        v=e[u][i];        if(!vis[v])        {            vis[v]=1;            if(pre[v]==-1||find(pre[v]))            {                pre[v]=u;                return 1;            }        }    }    return 0;}int main(){    int n,m,num;    while(scanf("%d%d",&n,&m)!=EOF)    {        if(n==0&&m==0)break;        scanf("%d",&num);        int i,j,k,a,b,x,y,x1,y1,x2,y2;        memset(map,0,sizeof(map));        for(i=0;i<num;i++)        {            scanf("%d%d",&a,&b);            map[a][b]=1;        }        for(i=1;i<=n*m;i++)            e[i].clear();        for(i=1;i<=n;i++)        {            for(j=1;j<=m;j++)            {                if(!map[i][j]&&(i+j)%2)                {                    for(k=0;k<4;k++)                    {                        x=i+dir[k][0];                        y=j+dir[k][1];                        if(x<=0||y<=0||x>n||y>m||map[x][y])continue;                        e[(i-1)*m+j].push_back(((x-1)*m+y));                    }                }            }        }        int ans=0;        memset(pre,-1,sizeof(pre));        for(i=1;i<=n*m;i++)        {            memset(vis,0,sizeof(vis));            ans+=find(i);        }        printf("%d\n",ans);        for(i=1;i<=n*m;i++)        {            if(pre[i]==-1)continue;            if(pre[i]%m==0){x1=pre[i]/m;y1=m;}            else{x1=pre[i]/m+1;y1=pre[i]%m;}            if(i%m==0){x2=i/m;y2=m;}            else{x2=i/m+1;y2=i%m;}            printf("(%d,%d)--(%d,%d)\n",x1,y1,x2,y2);        }        printf("\n");    }    return 0;}/*    n*m的矩阵,标号1~n*m,则以相邻空白格的编号建边,则边表示的就是可选的1*2的格子。    分二部图:由于横纵坐标相加为奇数的点,跟它相邻的必定是横纵坐标相加为偶数的点,且所有奇数点加相邻偶数点覆盖所有图上的点。由此我们可以从奇数点到偶数点建二部图。    最大匹配:二分图G中,找出边数最大的子图M,使得M中各条边均无公共顶点,则M为最大匹配。    所求答案ans=最大匹配数,因为所求情况必定符合匹配,因为不能有覆盖的格子,因而最大匹配数就是所求最大的1*2格数        最后pre记录的符合最大匹配的点和它的相连点,即所求边*/

原创粉丝点击