您的位置:首页 > 编程语言 > Go语言

LightOJ - 1152 Hiding Gold /poj 3041 二分匹配@

2016-07-26 10:33 525 查看
Hiding Gold

Time Limit: 2000MSMemory Limit: 32768KB64bit IO Format: %lld & %llu
Submit Status 

uDebug


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 2x 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
, match
, s

;
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
char str

;
vector<int>G
;
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

Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice points of
the grid. 

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.

Input
* Line 1: Two integers N and K, separated by a single space. 

* 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.

Output
* Line 1: The integer representing the minimum number of times Bessie must shoot.

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


Sample Output
2


Hint
INPUT DETAILS: 

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
, vis
;
vector<int>G
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: