blue sea  
As an ACMer, not only try, but also create.

很好的一道题目。
题意:给定一个 M * N 大小的方格,地图有3中方格,墙、草地、空地。他的老板希望Robert能在地图中放置尽可能多的机器人。每个机器人可以向四个方向开火,激光可以穿透草地,但不能穿透墙壁。(http://www.cnblogs.com/g0feng/archive/2012/11/10/2763771.html)
求出最大可以放置的机器人数。
思路:
建图方式:矩阵横竖块建二分图,将问题转化为最大匹配问题。
这题是《图论算法理论、实现及应用》书中的例题,有详细的分析P361

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 // Accepted  1654 C++ 50ms 6840K 
 6 #define MAXN 51
 7 int xx, yy, x[MAXN*MAXN], y[MAXN*MAXN], xs[MAXN][MAXN], ys[MAXN][MAXN];
 8 char Graph[MAXN][MAXN];
 9 int vis[MAXN*MAXN];
10 bool map[MAXN*MAXN][MAXN*MAXN];
11 int row, col;
12 bool dfs( int u )
13 {
14     int v;
15     for( v = 1; v <= yy; v++ )
16     {
17         if( map[u][v] && !vis[v] )
18         {
19             vis[v] = 1;
20             if( !y[v] || dfs( y[v] ) )
21             {
22                 x[u] = v;
23                 y[v] = u;
24                 return true;
25             }
26         }
27     }
28     return false;
29 }
30 void MaxMatch()
31 {
32     int u, ans = 0;
33     memset( x, 0, sizeof(x) );
34     memset( y, 0, sizeof(y) );
35     for( u = 1; u <= xx; u++ )
36     {
37         if( !x[u] )
38         {
39             memset( vis, 0, sizeof(vis) );
40             if( dfs( u ) )ans++;
41         }
42     }
43     printf( "%d\n", ans );
44 }
45 int main()
46 {
47     int cas, i, j, k, tot, flag;
48     scanf( "%d", &cas );
49     for( k = 1; k <= cas; k++ )
50     {
51         memset( xs, 0, sizeof(xs) );
52         memset( ys, 0, sizeof(ys) );
53         scanf( "%d%d", &row, &col );
54         for( i = 0; i < row; i++ )
55             scanf( "%s", Graph[i] );
56         tot = 0;
57         for( i = 0; i < row; i++ )
58         {
59             flag = 0;
60             for( j = 0; j < col; j++ )
61             {
62                 if( Graph[i][j] == 'o' )
63                 {
64                     if( !flag )tot++;
65                     xs[i][j] = tot;    flag = 1;
66                 }
67                 else if( Graph[i][j] == '#' )
68                     flag = 0;
69             }
70         }
71         xx = tot;
72         tot = 0;
73         for( j = 0; j < col; j++ )
74         {
75             flag = 0;
76             for( i = 0; i < row; i++ )
77             {
78                 if( Graph[i][j] == 'o' )
79                 {
80                     if( !flag )tot++;
81                     ys[i][j] = tot;    flag = 1;
82                 }
83                 else if( Graph[i][j] == '#' )
84                     flag = 0;
85             }
86         }
87         yy = tot;
88         memset( map, 0, sizeof(map) );
89         for( i = 0; i < row; i++ )
90             for( j = 0; j < col; j++ )
91                 if( xs[i][j] )map[xs[i][j]][ys[i][j]] = 1;
92         printf( "Case :%d\n", k );
93         MaxMatch();
94     }
95 }

 

posted on 2013-01-23 19:33  wide sea  阅读(193)  评论(0)    收藏  举报