Why so serious? --[NKU]schindlerlee

2010年02月07日星期日.sgu190 二分图

2010年02月07日星期日.sgu190
sgu190:
一开始想到的竟然是状态压缩dp,然后一看n,貌似大了点。
然后怎么想也没思路,上网看看,才知道原来二分图还可以这么用,我怎么从来也没想到呢。。。。

将图像国际象棋棋盘那样黑白染色,然后给对于每个颜色给每个格子一个编号。
然后选一个染色,对每个格子和他旁边的格子建边,这样构成一个二分图。
求出最大的匹配数,然后再按照题目的猥琐要求输出即可。

注意 题目中棋盘的格式是这个样子的。
(2,1) (2,2)
(1,1) (1,2)
左下角是(1,1)
如果按照平常的左上角是(1,1)来搞,需要注意一下输出

  1 
  2 int g[801][801],n,P;
  3 const int BLACK = 1;
  4 const int WHITE = 2;
  5 const int REMOVED = 3;
  6 int num[41][41],bsp,wsp,cnt;
  7 int board[41][41];
  8 int bcoord[41*41][2];
  9 int wcoord[41*41][2];
 10 int vis[801];
 11 int L[801],R[801];
 12 
 13 bool make_graph()
 14 {
 15   int i,j;cnt = 0;
 16   for (i = 1;i <= n;i++) {
 17       for (j = 1;j <= n;j++) {
 18           if (board[i][j] != REMOVED) {
 19               cnt ++;
 20               if ((i+j)%2==1) {
 21                   board[i][j] = WHITE;
 22                   wcoord[wsp][0= i, wcoord[wsp][1= j;
 23                   num[i][j] = wsp++;
 24               }else {
 25                   board[i][j] = BLACK;
 26                   bcoord[bsp][0= i, bcoord[bsp][1= j;
 27                   num[i][j] = bsp++;
 28               }
 29           }
 30       }
 31   }
 32   for (i = 1;i <= n;i++) {
 33       for (j = 1;j <= n;j++) {
 34           if (board[i][j] == BLACK) {
 35               if (board[i+1][j] == WHITE) g[num[i][j]][num[i+1][j]] = 1;
 36               if (board[i][j+1== WHITE) g[num[i][j]][num[i][j+1]] = 1;
 37               if (board[i-1][j] == WHITE) g[num[i][j]][num[i-1][j]] = 1;
 38               if (board[i][j-1== WHITE) g[num[i][j]][num[i][j-1]] = 1;
 39           }
 40       }
 41   }
 42   return true;
 43 }
 44 
 45 bool dfs(int u) {
 46   for (int v = 0;v < wsp;v++) {
 47       if (g[u][v] && !vis[v]) {
 48           vis[v] = true;
 49           if (R[v] == -1 || dfs(R[v])) {
 50               L[u] = v;
 51               R[v] = u;
 52               return true;
 53           }
 54       }
 55   }
 56   return false;
 57 }
 58 
 59 int MaxMatch()
 60 {
 61   int i,res = 0;
 62   memset(L,-1,sizeof(L));
 63   memset(R,-1,sizeof(R));
 64 
 65   for (i = 0;i < bsp;i++) {
 66       if (L[i] == -1) {
 67           memset(vis,0,sizeof(vis));
 68           if (dfs(i)) {
 69               res++;
 70           }
 71       }
 72   }
 73   return res;
 74 }
 75 
 76 int out[801][2],top;
 77 bool proc()
 78 {
 79   make_graph(); if (cnt & 1) { return false; }
 80   if (bsp == 0 || wsp == 0) { return false; }
 81   if (bsp != wsp) { return false; }
 82   return (MaxMatch() * 2 == cnt);
 83 }
 84 
 85 int main()
 86 {
 87   int i,j,k,a,b;
 88   scanf("%d%d",&n,&P);
 89   for (i = 0;i < P;i++) {
 90       scanf("%d%d",&a,&b);
 91       board[a][b] = REMOVED;
 92   }
 93   if (proc()) {
 94       printf("Yes\n");
 95       top = 0;
 96       for (i = 0;i < bsp;i++) {
 97           if (bcoord[i][1== wcoord[L[i]][1]) {
 98               if (bcoord[i][0< wcoord[L[i]][0]) {
 99                   out[top][0= bcoord[i][0];
100                   out[top][1= bcoord[i][1];
101                   top++;
102               }else {
103                   out[top][0= wcoord[L[i]][0];
104                   out[top][1= wcoord[L[i]][1];
105                   top++;
106               }
107           }
108       }
109 
110       printf("%d\n",top);
111       for (i = 0;i < top;i++) { printf("%d %d\n",out[i][0],out[i][1]); }
112 
113       top = 0;
114       for (i = 0;i < bsp;i++) {
115           if (bcoord[i][0== wcoord[L[i]][0]) {
116               if (bcoord[i][1< wcoord[L[i]][1]) {
117                   out[top][0= bcoord[i][0];
118                   out[top][1= bcoord[i][1];
119                   top++;
120               }else {
121                   out[top][0= wcoord[L[i]][0];
122                   out[top][1= wcoord[L[i]][1];
123                   top++;
124               }
125           }
126       }//http://www.cppblog.com/schindlerlee
127       printf("%d\n",top);
128       for (i = 0;i < top;i++) { printf("%d %d\n",out[i][0],out[i][1]); }
129   }else {
130       printf("No\n");
131   }
132 
133 
134   return 0;
135 }
136 
137 

posted on 2010-02-07 15:06 schindlerlee 阅读(1023) 评论(0)  编辑 收藏 引用 所属分类: 解题报告


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理