poj3041 二分图最小点覆盖

Asteroids
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 16247   Accepted: 8837

Description

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

行看成X部,列看成Y部,若(Xi,Yi)有小行星,那么就在Xi和Yi之间连一条线,这样我们只要求一个最小点覆盖即可,因为每覆盖一条边,就相当于炸掉一颗小行星。二分图最小点覆盖=最大匹配。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#define Maxn 510
using namespace std;

int adj[Maxn][Maxn];
int match[Maxn];
int vis[Maxn];
int x,y;
int deep;
bool dfs(int u){
    for(int v=1;v<=y;v++){
        if(adj[u][v]&&vis[v]!=deep){
            vis[v]=deep;
            if(match[v]==-1||dfs(match[v])){
                match[v]=u;
                return true;
            }
        }
    }
    return false;
}
int hungary(){
    memset(match,-1,sizeof match);
    memset(vis,-1,sizeof vis);
    int ans=0;
    for(int i=1;i<=x;i++){
        deep=i;
        if(dfs(i)) ans++;
    }
    return ans;
}
int main()
{
    int n,m,a,b;
    while(cin>>n>>m){
        x=y=n;
        for(int i=0;i<m;i++){
            cin>>a>>b;
            adj[a][b]=1;
        }
        printf("%d\n",hungary());
    }
	return 0;
}


poj2226:这题和上面建图不同,思想类似。此题不是按行和列来建图的,是按照每行连续的块和每列连续的块来建图。

Muddy Fields
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8615   Accepted: 3181

Description

Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 50, 1 <= C <= 50). While good for the grass, the rain makes some patches of bare earth quite muddy. The cows, being meticulous grazers, don't want to get their hooves dirty while they eat. 

To prevent those muddy hooves, Farmer John will place a number of wooden boards over the muddy parts of the cows' field. Each of the boards is 1 unit wide, and can be any length long. Each board must be aligned parallel to one of the sides of the field. 

Farmer John wishes to minimize the number of boards needed to cover the muddy spots, some of which might require more than one board to cover. The boards may not cover any grass and deprive the cows of grazing area but they can overlap each other. 

Compute the minimum number of boards FJ requires to cover all the mud in the field.

Input

* Line 1: Two space-separated integers: R and C 

* Lines 2..R+1: Each line contains a string of C characters, with '*' representing a muddy patch, and '.' representing a grassy patch. No spaces are present.

Output

* Line 1: A single integer representing the number of boards FJ needs.

Sample Input

4 4
*.*.
.***
***.
..*.

Sample Output

4

Hint

OUTPUT DETAILS: 

Boards 1, 2, 3 and 4 are placed as follows: 
1.2. 
.333 
444. 
..2. 
Board 2 overlaps boards 3 and 4.

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#define Maxn 1260
using namespace std;

int adj[Maxn][Maxn];
int match[Maxn];
int vis[Maxn];
int x,y;
int deep;
bool dfs(int u){
    for(int v=1;v<=y;v++){
        if(adj[u][v]&&vis[v]!=deep){
            vis[v]=deep;
            if(match[v]==-1||dfs(match[v])){
                match[v]=u;
                return true;
            }
        }
    }
    return false;
}
int hungary(){
    memset(match,-1,sizeof match);
    memset(vis,-1,sizeof vis);
    int ans=0;
    for(int i=1;i<=x;i++){
        deep=i;
        if(dfs(i)) ans++;
    }
    return ans;
}
char s[60][60];
int r[60][60],c[60][60];
int main()
{
    int n,m;
    while(cin>>n>>m){
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        int tot=0;
        for(int i=0;i<n;i++){
            bool flag=false;
            for(int j=0;j<m;j++)
                if(s[i][j]=='*'){
                    if(!flag) {r[i][j]=++tot;flag=true;}
                    else r[i][j]=tot;
                }
                else flag=false;
        }
        x=tot;
        tot=0;
        for(int j=0;j<m;j++){
            bool flag=false;
            for(int i=0;i<n;i++)
                if(s[i][j]=='*'){
                    if(!flag) {c[i][j]=++tot;flag=true;}
                    else c[i][j]=tot;
                }
                else flag=false;
        }
        y=tot;
        memset(adj,0,sizeof adj);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(s[i][j]=='*') adj[r[i][j]][c[i][j]]=1;
        printf("%d\n",hungary());
    }
	return 0;
}


你可能感兴趣的:(poj3041 二分图最小点覆盖)