HDU1507 二分图 棋盘覆盖问题

 1 /*HDU1507
 2 
 3 */
 4 #include <iostream>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <string.h>
 8 #include <stdio.h>
 9 #include <set>
10 #include <stack>
11 #include <queue>
12 #include <vector>
13 #define maxn 11100
14 using namespace std;
15 
16 /*(x,y)--> num = (x-1) * (M) + y;
17    num -- >  (x,y) == (num/M+1 ,num % M)
18 */
19 vector<int>G[maxn];
20 bool visit[maxn];
21 int match[maxn];
22 int a[][2]={{0,-1},{0,1},{1,0},{-1,0}};
23 int N,M,K;
24 bool dfs(int s)//找到从s点出发的可增广路
25 {
26     for(int i=0;i<G[s].size();i++){
27         int v=G[s][i];
28         if (!visit[v]){
29             visit[v]=true;
30             if (match[v]==0 || dfs(match[v])){//说明v对应的项有增广路
31                 match[v]=s;//修改v的对应项(即互斥点)是s
32                 return true;
33             }
34         }
35     }
36     return false;
37 }
38 
39 int hungary(){
40     int ans=0;
41     memset(match,0,sizeof(match));//清空匹配
42     for(int i=1;i<=N*M;i++){
43         memset(visit,0,sizeof(visit));//注意清空增广路
44         if (dfs(i)) ans++;
45     }
46     return ans;
47 }
48 bool map[110][110];
49 void read(){
50     cin>>K;
51     memset(map,0,sizeof (map));
52     for(int i=1; i <=K ;i++){
53         int x,y;
54         scanf("%d%d",&x,&y);
55         map[x][y]=true;
56     }
57 }
58 void builtG(){
59     for(int i=1;i<=M*N;i++){
60         G[i].clear();
61     }
62     for(int i=1;i<=N;i++){
63         for(int j=1;j<=M;j++){
64             if (map[i][j] || (i+j)%2==0) continue;
65             for(int l=0;l<4;l++){
66                 int x=i+a[l][0],y=j+a[l][1];
67                 if ( x<1 || x>N || y<1 || y>M || map[x][y]) continue;
68 //                G[(x-1) * (M) + y].push_back((i-1) * (M) + j);
69                 G[(i-1) * (M) + j].push_back((x-1) * (M) + y);
70             }
71         }
72     }
73     return ;
74 }
75 void getxy(int num,int &x,int &y){
76     x = num/M + 1;
77     if (num % M == 0) x--;
78     y = num-(x-1)*M;
79 }
80 bool flag[maxn];
81 int main(){
82     while(~scanf("%d%d",&N,&M) && N && M){
83         read();
84         builtG();
85         printf("%d\n",hungary());
86         memset(flag,0,sizeof(flag));
87         for (int i=1;i<=N*M;i++){
88             if (match[i]==0) continue;
89             int x1,y1,x2,y2;
90             getxy(i,x1,y1);
91 //            cout<<"i="<<i<<","<<x<<","<<y<<endl;
92             getxy(match[i],x2,y2);
93             printf("(%d,%d)--(%d,%d)\n",x1 ,y1,x2,y2);
94             flag[i]=flag[match[i]]=true;
95         }
96         printf("\n");
97     }
98     return 0;
99 }

 

posted @ 2014-04-07 16:58  little_w  阅读(311)  评论(0编辑  收藏  举报