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 }

 

你可能感兴趣的:(HDU)