hdu1507 最大匹配

题目大意:

  在 n*m在矩阵中,有一些点被标记为黑色,问可以多少对相邻的没有重复的白色块。

思路:

  看上去与二分匹配毫无关系。但是没有其他好的解法,转化为二分匹配是正解。二分匹配的条件是{X,Y|E}, X(Y)集合内的元素没有关系。这题可以把i+j为奇数归为X,偶数则归为Y。从头开始扫描,只要某点不是黑色的,那么可以试着向上下左右建边,不过也需要四个方向的点不是黑色才可以。由于n ,m <=100,所有点数有10000,所有用邻接矩阵存图会超内存。用邻接表存图就好了。邻接表的存图方式是建立一个动态数组,如果有边u->v,则将v存入u的数组。

  

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #include<vector>
  6 #include<algorithm>
  7 using namespace std;
  8 const int N=10150,INF=0x3f3f3f3f;
  9 int cx[N],cy[N],dx[N],dy[N],vis[102][102];
 10 bool bmask[N];
 11 int nx,ny,dis,ans;
 12 vector<int> bmap[N];
 13 bool searchpath()
 14 {
 15     queue<int> q;
 16     dis=INF;
 17     memset(dx,-1,sizeof(dx));
 18     memset(dy,-1,sizeof(dy));
 19     for(int i=1;i<=nx;i++)
 20     {
 21         if(cx[i]==-1){ q.push(i); dx[i]=0; }
 22         while(!q.empty())
 23         {
 24             int u=q.front(); q.pop();
 25             if(dx[u]>dis) break;
 26             for(int i=0;i<bmap[u].size();i++)
 27             {
 28                 int v=bmap[u][i];
 29                 if(dy[v]==-1)
 30                 {
 31                     dy[v]= dx[u] + 1;
 32                     if(cy[v]==-1) dis=dy[v];
 33                     else
 34                     {
 35                         dx[cy[v]]= dy[v]+1;
 36                         q.push(cy[v]);
 37                     }
 38                 }
 39             }
 40         }
 41     }
 42     return dis!=INF;
 43 }
 44 int findpath(int u)
 45 {
 46     for(int i=0;i<bmap[u].size();i++)
 47     {
 48         int v=bmap[u][i];
 49         if(!bmask[v]&&dy[v]==dx[u]+1)
 50         {
 51             bmask[v]=1;
 52             if(cy[v]!=-1&&dy[v]==dis) continue;
 53             if(cy[v]==-1||findpath(cy[v]))
 54             {
 55                 cy[v]=u; cx[u]=v;
 56                 return 1;
 57             }
 58         }
 59     }
 60     return 0;
 61 }
 62 void maxmatch()
 63 {
 64     ans=0;
 65     memset(cx,-1,sizeof(cx));
 66     memset(cy,-1,sizeof(cy));
 67     while(searchpath())
 68     {
 69         memset(bmask,0,sizeof(bmask));
 70         for(int i=1;i<=nx;i++)
 71             if(cx[i]==-1) ans+=findpath(i);
 72     }
 73 }
 74 void init()
 75 {
 76     for(int i=0;i<N;i++) bmap[i].clear();
 77     memset(vis,0,sizeof(vis));
 78 }
 79 int main()
 80 {
 81     //freopen("test.txt","r",stdin);
 82     int n,m,t,i,j,k,a,b;
 83     while(scanf("%d%d",&n,&m)!=EOF)
 84     {
 85         if(!n) break;
 86         init();
 87         scanf("%d",&t);
 88         while(t--)
 89         {
 90             scanf("%d%d",&i,&j);
 91             vis[i][j]=1;
 92         }
 93         for(i=1;i<=n;i++)
 94         {
 95             for(j=1;j<=m;j++)
 96             {
 97                 if(!vis[i][j]&&((i+j)%2))
 98                 {
 99                     a=(i-1)*m + j;
100                     if(!vis[i][j-1]&&j>1) //
101                     {
102                         b=a-1;
103                         bmap[a].push_back(b);
104                     }
105                     if(!vis[i][j+1]&&j<m) //
106                     {
107                         b=a+1;
108                         bmap[a].push_back(b);
109                     }
110                     if(!vis[i-1][j]&&i>1)   //
111                     {
112                         b=a-m;
113                         bmap[a].push_back(b);
114                     }
115                     if(!vis[i+1][j]&&i<n)   //
116                     {
117                         b=a+m;
118                         bmap[a].push_back(b);
119                     }
120                 }
121             }
122         }
123         nx=ny=n*m;
124         maxmatch();
125         printf("%d
",ans);
126         for(i=1;i<=n*m;i++)
127         {
128             if(cx[i]==-1) continue;
129             a=i/m; b=i%m;
130             if(!b) b=m; else a++;
131             printf("(%d,%d)--",a,b);
132             a=cx[i]/m; b=cx[i]%m;
133             if(!b) b=m; else a++;
134             printf("(%d,%d)
",a,b);
135         }
136     }
137     return 0;
138 }
View Code

  

原文地址:https://www.cnblogs.com/Potato-lover/p/3985237.html