Link:
Nyoj 237: Click Here ~~
Poj 3041 asteroids: Click Here ~~
Question:
The two questions are the same, but the translation is different.
-
A legend-level game expert played a small game in his spare time. In the game, there were many enemies in an N * n Square area, players can use bombs to blow up all enemies in a row or column. He is a kind of player who wants to play well in any game, so he decided to use as few bombs as possible to blow up all the enemies.
Now let's give you a game status. Please help him determine the minimum number of bombs required to blow up all the enemies.
For exampleXIndicates the enemy
X. x
. X.
. X.
Then, he only needs to blow up 1st rows and 2nd columns to blow up all the enemies, so he only needs two bombs.
-
Input
-
The first line is an integer T, indicating the number of groups of test data (0 <t <= 400 ).
The first row of each group of test data has two integers, N and K. N indicates the size of the square area of the game. (N <= 500, k <= 10 000)
In the subsequent K rows, each row has two integers (I). J indicates row I, and column J has an enemy (the row and column are numbered from 1 ). (1 <= I, j <= N)
-
Output
-
For each group of test data, an integer is output to indicate the minimum number of bombs required.
-
Sample Input
-
13 41 11 32 23 2
-
Sample output
-
2
Ideas:
The bomb attack path is treated as the vertex of the graph, and the enemy is treated as the edge corresponding to the connection path. After conversion, the attack path scheme corresponds to a vertex set S, however, it is required that a bomb can blow up all enemies. In other words, each side of the graph has at least one endpoint belonging to S, the problem is converted to finding the vertex set S that meets the preceding requirements at the minimum ., The edges corresponding to the position of each enemy are connected to a horizontal vertex and a vertical vertex respectively. Each column is regarded as a vertex and each row is regarded as a vertex, if an edge exists between a row node and a column node, it indicates that this column has an enemy. Therefore, a bipartite graph is used to match a bipartite graph. In this case, the minimum point set overwrite = the minimum matching of a bipartite graph is also designed. You can learn your own materials without understanding the relevant algorithm knowledge.
Legend:
More detailedMinimum vertex coverage = maximum number of matchesIdea: refer to: click here
Code:
#include <math.h>#include <queue>#include <deque>#include <vector>#include <stack>#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;#define Max(a,b) a>b?a:b#define Min(a,b) a>b?b:a#define mem(a,b) memset(a,b,sizeof(a))int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};const int maxn=502;struct Edge{ int v;};int n, k;vector <int > mapp[maxn];int vis[maxn], connect[maxn];int dfs(int u){ int i; for(i =0; i<mapp[u].size(); i++) { int xx=mapp[u][i]; if(!vis[xx]) { vis[xx] =1; if (!connect[xx]|| dfs(connect[xx])) { connect[xx] = u; return 1; } } } return 0;}int main(){ //freopen("1.txt","r",stdin); //freopen("2.txt","w",stdout); int cas; scanf("%d",&cas); while(cas--) { int sum=0; scanf("%d%d", &n, &k); for (int i =0; i <maxn; i++) mapp[i].clear(); for (int i =1; i <=k; i++) { int a, b; scanf("%d%d", &a, &b); mapp[a].push_back(b); } memset(connect,0, sizeof(connect)); for(int i =1; i <=n; i++) { memset(vis, 0, sizeof(vis)); if (dfs(i)) sum++; } printf("%d\n",sum); } return 0;}
Optimization code ():
#include <stdio.h>#include <string.h>const int N = 505;const int M = 10005;struct Vertex{ int head;}V[N];struct Edge{ int v,next;}E[M];int top,match[N];bool used[N];void Init(){ top = 0; memset(V,-1,sizeof(V)); memset(match,0,sizeof(match));}void Add_Edge(int u,int v){ E[top].v = v; E[top].next = V[u].head; V[u].head = top++;}bool dfs(int u){ for(int i=V[u].head;~i;i=E[i].next) { int v = E[i].v; if(!used[v]) { used[v] = true; if(!match[v] || dfs(match[v])) { match[v] = u; return true; } } } return false;}int maxMatch(int n){ int ans = 0; for(int i=1;i<=n;i++) { memset(used,false,sizeof(used)); if(dfs(i)) ++ans; } return ans;}int main(){ int z,n,m,num; scanf("%d",&z); while(z--) { Init(); scanf("%d%d",&n,&m); while(m--) { int i,j; scanf("%d%d",&i,&j); Add_Edge(i,j); } printf("%d\n",maxMatch(n)); } return 0;}
Nyoj 237 game master Troubles & POJ3041-Asteroids (maximum matching of Bipartite Graph)