Description You are given a 2D board where in some cells there are gold. You want to fill the board with 2 x 1 dominoes such that all gold are covered. You may use the dominoes vertically or horizontally and the dominoes may overlap. All you have to do is to cover the gold with least number of dominoes. In the picture, the golden cells denote that the cells contain gold, and the blue ones denote the 2 x 1 dominoes. The dominoes may overlap, as we already said, as shown in the picture. In reality the dominoes will cover the full 2 x 1 cells; we showed small dominoes just to show how to cover the gold with 11 dominoes. Input Input starts with an integer T (≤ 50), denoting the number of test cases. Each case starts with a row containing two integers m (1 ≤ m ≤ 20) and n (1 ≤ n ≤ 20) and m * n > 1. Here m represents the number of rows, and n represents the number of columns. Then there will be m lines, each containing n characters from the set ['*','o']. A '*' character symbolizes the cells which contains a gold, whereas an 'o' character represents empty cells. Output For each case print the case number and the minimum number of dominoes necessary to cover all gold ('*' entries) in the given board. Sample Input 2 5 8 oo**oooo *oo*ooo* ******oo *o*oo*oo ******oo 3 4 **oo **oo *oo* Sample Output Case 1: 11 Case 2: 4 Source
Problem Setter: Jane Alam Jan
给一个图和一些坐标点,要用2*1的方格去覆盖,求把所有坐标点都覆盖的最下方格数
将奇数点与偶数点匹配,用总和减去匹配数=最大独立子集,因为没有给序号需要自己将出现过的点标记为一个序号
注意容器的更新,遍历的条件
| ![]() |
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 1000;
int used[N], match[N], s[N][N];
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
char str[N][N];
vector<int>G[N];
int n, m;
int dfs(int x);
int main()
{
int t, ncase=1;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
int odd=0,even=0;
memset(match,0,sizeof(match));
memset(s,0,sizeof(s));
memset(str,'\0',sizeof(str));
for(int i=0; i<n; i++)
{
scanf("%s",str[i]);
}
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(str[i][j]=='*')
{
if((i+j)&1)
{
s[i][j]= ++odd;
}
else
{
s[i][j]= ++even;
}
}
}
}
for(int i=0;i<=odd;i++)
{
G[i].clear();
}
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(str[i][j]=='*'&&((i+j)&1))
{
for(int k=0; k<4; k++)
{
int x=i+dir[k][0], y=j+dir[k][1];
if(x>=0&&x<n&&y>=0&&y<m&&str[x][y]=='*')
{
G[s[i][j]].push_back(s[x][y]);
}
}
}
}
}
int num=0;
for(int i=1; i<=odd; i++)
{
memset(used,0,sizeof(used));
if(dfs(i))
{
num++;
}
}
printf("Case %d: %d\n",ncase++,odd+even-num);
}
return 0;
}
int dfs(int x)
{
for(int i=0; i<G[x].size(); i++)
{
int v=G[x][i];
if(used[v]==0)
{
used[v]=1;
if(match[v]==0||dfs(match[v]))
{
match[v]=x;
return 1;
}
}
}
return 0;
}
poj 3041
Fortunately, Bessie has a powerful weapon that can vaporize all the asteroids in any given row or column of the grid with a single shot.This weapon is quite expensive, so she wishes to use it sparingly.Given the location of all the asteroids in the field, find the minimum number of shots Bessie needs to fire to eliminate all of the asteroids.
* Lines 2..K+1: Each line contains two space-separated integers R and C (1 <= R, C <= N) denoting the row and column coordinates of an asteroid, respectively.
3 4 1 1 1 3 2 2 3 2
2
The following diagram represents the data, where "X" is an asteroid and "." is empty space:
X.X
.X.
.X.
OUTPUT DETAILS:
Bessie may fire across row 1 to destroy the asteroids at (1,1) and (1,3), and then she may fire down column 2 to destroy the asteroids at (2,2) and (3,2).
给出一个n*n的图,和一些点坐标,每次可以删除一整列或一整行,求把所有点删除的最小删除次数;
可以把行和列拆成俩个顶点,坐标是连接行和列的线,求最小顶点覆盖
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 1010;
const int mod = 1e9+7;
int a[1010][1010], match[N], vis[N];
vector<int>G[N];
int dfs(int u)
{
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(vis[v]==0)
{
vis[v]=1;
if(match[v]==-1||dfs(match[v]))
{
match[v]=u;
return 1;
}
}
}
return 0;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for(int i=0;i<=n;i++) G[i].clear();
memset(a,0,sizeof(a));
for(int i=0;i<m;i++)
{
int x, y;
scanf("%d %d", &x, &y);
G[x].push_back(y);
a[x][n+y]=1;
}
memset(match,-1,sizeof(match));
int cnt=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))
cnt++;
}
printf("%d\n",cnt);
return 0;
}