hdu-1281. Board games (bipartite graph bipartite graph matching + key point inquiry)

board game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7898    Accepted Submission(s): 4600


Problem Description
Little hope and Gardon playing a game: for a N * M chessboard, as many in the grid to put some chess inside the "car", and that could put them attack each other, which of course is very simple, but Gardon limits only lattice can put some small hope is still very easy to solve this problem (see below) can not pay attention to where to put the car does not affect the car's attack each other. 
So now Gardon want a little hope to solve the problem more difficult, to ensure as much as possible, "car" under the premise of the board in some lattice can be avoided, that is, not to put these cars on the grid, you can ensure as much as possible "car" to be put down. However, some sub-lattice if hold, we can not guarantee to put as much as possible, "car", this grid is called an important point. How many Gardon want such an important point there is little hope calculate, you can solve this problem?
 

 

Input
Input comprising a plurality of sets of data, 
the first row has three numbers N, M, K (1 < N, M <= 100 1 <K <= N * M), shows a board height, width, and can put "car" the number of lattice. The following describes the information of all K rows of the grid: Each row two numbers X and Y, represents the position of the grid in the board.
 

 

Output
Each set of input data, in accordance with the format of the output is as follows: 
Board have have C T L Important Blanks for chessmen.
 

 

Sample Input
3 3 4 1 2 1 3 2 1 2 2 3 3 4 1 2 1 3 2 1 3 2
 

 

Sample Output
Board 1 have 0 important blanks for 2 chessmen. Board 2 have 3 important blanks for 3 chessmen.
 

 

Author
Roach
 

 

Source
 

 

Recommend
lcy
 
  1  / * *********************************************** *************************
   2      > File the Name: HDU-1281 board game .cpp.
   3      > Author: CruelKing
   4      > Mail: 2,016,586,625 @ QQ .com 
   5      > the Created time: 2019 Nian 08 Wednesday, 28 May 09 hours 49 minutes 22 seconds
   6      of this topic and ideas: the focus of this question is how to solve the important side, the simplest idea is to enumerate all sides, found the largest after If you remove an edge reducing the number of matches, then this edge is the key point of the corresponding point.
  7      Second, there is less of a complex idea is for each side is already matched, delete this side, we had no match in all the vertices as a starting point to go to match the side, if you find you can then match to Note you can also find other augmenting path, meaning it can have other side instead of matching edges of this match, then the point is not critical point, otherwise the point is the key point.
  8  ************************************************* ************************************************************ * / 
  . 9  / * 
10  #include <cstdio>
 . 11 #include <cstring>
 12 using namespace std;
 13 
 14 const int maxn = 100 + 5, maxm = 100 * 100 + 5;
 15 int linker[maxn], ui[maxn], vi[maxn];
 16 bool used[maxn], g[maxn][maxn];
 17 int n, m;
 18 
 19 bool dfs(int u) {
 20     for(int v = 1; v <= m; v ++) {
 21         if(g[u][v] && !used[v]) {
 22             used[v] = true;
 23             if(linker[v] == -1 || dfs(linker[v])) {
 24                 linker[v] = u;
 25                 return true;
 26             }
 27         }
 28     }
 29     return false;
 30 }
 31 
 32 int hungary() {
 33     int res = 0;
 34     memset(linker, -1, sizeof linker);
 35     for(int i = 1; i <= n; i ++) {
 36         memset(used, false, sizeof used);
 37         if(dfs(i)) res ++;
 38     }
 39     return res;
 40 }
 41 
 42 int main() {
 43     int k, u, v, Case = 0;
 44     while(~scanf("%d %d %d", &n, &m, &k)) {
 45         memset(g, false, sizeof g);
 46         for(int i = 0; i < k; i ++) {
 47             scanf("%d %d", &ui[i], &vi[i]);
 48             g[ui[i]][vi[i]] = true;
 49         }
 50         int res1 = hungary(), cnt = 0;
 51         for(int i = 0; i < k; i ++) {
 52             g[ui[i]][vi[i]] = false;
 53             int res2 = hungary();
 54             if(res2 < res1) cnt ++;
 55             g[ui[i]][vi[i]] = true;
 56         }
 57         printf("Board %d have %d important blanks for %d chessmen.\n", ++ Case, cnt, res1);
 58     }
 59     return 0;
 60 }
 61 */
 62 
 63 #include <cstdio>
 64 #include <cstring>
 65 using namespace std;
 66 
 67 const int maxn = 100 + 5;
 68 int n, m, k;
 69 int linkery[maxn], linkerx[maxn];
 70 bool used[maxn], g[maxn][maxn];
 71 bool flag;
 72 
 73 bool dfs(int u) {
 74     for(int v = 1; v <= m; v ++) {
 75         if(g[u][v] && !used[v]) {
 76             used[v] = true;
 77             if(linkery[v] == -1 || dfs(linkery[v])) {
 78                 if(flag) {
 79                     linkery[v] = u;
 80                     linkerx[u] = v;
 81                 }
 82                 return true;
 83             }
 84         }
 85     }
 86     return false;
 87 }
 88 
 89 int hungary() {
 90     flag = true;
 91     memset(linkery, -1, sizeof linkery);
 92     memset(linkerx, -1, sizeof linkerx);
 93     int res = 0;
 94     for(int i = 1; i <= n; i ++) {
 95         memset(used, false, sizeof used);
 96         if(dfs(i)) res ++;
 97     }
 98     return res;
 99 }
100 
101 bool can() {
102     flag = false;
103     for(int u = 1; u <= n; u ++) {
104         if(linkerx[u] == -1) {
105             memset(used, false, sizeof used);
106             if(dfs(u)) return true;
107         }
108     }
109     return false;
110 }
111 
112 int main() {
113     int u, v, Case = 0;
114     while(~scanf("%d %d %d", &n, &m, &k)) {
115         memset(g, false, sizeof g);
116         for(int i = 0; i < k; i ++) {
117             scanf("%d %d", &u, &v);
118             g[u][v] = true;
119         }
120         int ans = hungary();
121         int res = 0, temp;
122         for(int i = 1; i <= n; i ++) {
123             if(~linkerx[i]) {
124                 temp = linkerx[i];
125                 linkerx[i] = linkery[temp] = -1;
126                 g[i][temp] = false;
127                 if(!can()) res ++;
128                 linkerx[i] = temp;
129                 linkery[temp] = i;
130                 g[i][temp] = true;
131             }
132         }
133         printf("Board %d have %d important blanks for %d chessmen.\n", ++ Case, res, ans);
134     }
135     return 0;
136 }

 

Guess you like

Origin www.cnblogs.com/bianjunting/p/11423276.html