hdu 1507 记录路径的二分匹配 **

题意:N*M的矩形,向其中填充1*2的小块矩形,黑色的部分不能填充,问最多可以填充多少块。
链接:点我
黑白棋最大匹配
将棋盘中i+j为奇数的做A集合,偶数的做B集合,相邻的则建立联系。于是便转换成寻找最大匹配的问题

 

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 #define MOD 1000000007
 10 const int INF=0x3f3f3f3f;
 11 const double eps=1e-5;
 12 typedef long long ll;
 13 #define cl(a) memset(a,0,sizeof(a))
 14 #define ts printf("*****\n");
 15 const int MAXN=510;
 16 int a[110][110];
 17 int b[100];
 18 int n,m,tt;
 19 /* ***********************************************************
 20 //二分图匹配(匈牙利算法的DFS实现)(邻接矩阵形式)
 21 //初始化:g[][]两边顶点的划分情况
 22 //建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配
 23 //g没有边相连则初始化为0
 24 //uN是匹配左边的顶点数,vN是匹配右边的顶点数
 25 //调用:res=hungary();输出最大匹配数
 26 //优点:适用于稠密图,DFS找增广路,实现简洁易于理解
 27 //时间复杂度:O(VE)
 28 //************************************************************ */
 29 //顶点编号从0开始的
 30 int uN,vN;//u,v的数目,使用前面必须赋值
 31 int g[MAXN][MAXN];//邻接矩阵
 32 int linker[MAXN];
 33 bool used[MAXN];
 34 bool dfs(int u)
 35 {
 36     for(int v = 0; v < vN;v++)
 37     if(g[u][v] && !used[v])
 38     {
 39         used[v] = true;
 40         if(linker[v] == -1 || dfs(linker[v]))
 41         {
 42             linker[v] = u;
 43             return true;
 44         }
 45     }
 46     return false;
 47 }
 48 int hungary()
 49 {
 50     int res = 0;
 51     memset(linker,-1,sizeof(linker));
 52     for(int u = 0;u < uN;u++)
 53     {
 54         memset(used,false,sizeof(used));
 55         if(dfs(u))res++;
 56     }
 57     return res;
 58 }
 59 int main()
 60 {
 61     int i,j,k;
 62     #ifndef ONLINE_JUDGE
 63     freopen("1.in","r",stdin);
 64     #endif
 65     while(scanf("%d%d",&n,&m)!=EOF)
 66     {
 67         if(n==0&&m==0)  break;
 68         scanf("%d",&k);
 69         int u,v;
 70         cl(a);
 71         while(k--)
 72         {
 73             scanf("%d%d",&u,&v);
 74             u--,v--;
 75             a[u][v]=-1;
 76         }
 77         int tot=0;
 78         for(i=0;i<n;i++)
 79         {
 80             for(j=0;j<m;j++)
 81             {
 82                 if(a[i][j]!=-1)
 83                 {
 84                     b[tot]=i*m+j;
 85                     a[i][j]=tot++;
 86                 }
 87             }
 88         }
 89         cl(g);
 90         for(i=0;i<n;i++)
 91         {
 92             for(j=0;j<m;j++)
 93             {
 94                 if(a[i][j]!=-1&&((i+j)%2==1))
 95                 {
 96                     int w=a[i][j];
 97                     if(i>0&&a[i-1][j]!=-1)
 98                         g[w][a[i-1][j]]=1;
 99                     if(i<n-1&&a[i+1][j]!=-1)
100                         g[w][a[i+1][j]]=1;
101                     if(j>0&&a[i][j-1]!=-1)
102                         g[w][a[i][j-1]]=1;
103                     if(j<m-1&&a[i][j+1]!=-1)
104                         g[w][a[i][j+1]]=1;
105                 }
106             }
107         }
108         vN=uN=tot;
109         printf("%d\n",hungary());
110         for(i=0;i<tot;i++)
111         {
112             if(linker[i]!=-1)
113             {
114                 int x1=b[i]/m;
115                 int y1=b[i]%m;
116                 int x2=b[linker[i]]/m;
117                 int y2=b[linker[i]]%m;
118                 printf("(%d,%d)--(%d,%d)\n",x1+1,y1+1,x2+1,y2+1);
119             }
120         }
121         printf("\n");
122     }
123 }

 

posted @ 2015-07-03 10:56  miao_a_miao  阅读(126)  评论(0编辑  收藏  举报