poj3041(二分匹配简单题)

题目链接:http://poj.org/problem?id=3041


Asteroids

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14022   Accepted: 7629

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

Source

USACO 2005 November Gold

这也是一道比较简单的二分匹配的题目。把光束当作图的顶点,而把小行星当作连接对应光束的边,如此一来,光束的攻击方案即对应一个顶点集合s。图中每一条边至少有一个属于s的端点。转换成了最小顶点覆盖问题。

在二分图中     最大匹配=最小顶点覆盖

于是用二分匹配可解:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int MAX=1010;
vector<int> G[MAX];
int match[MAX],r[MAX],c[MAX];
bool used[MAX];
int k,V,n;
void add_edge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}
bool dfs(int v)
{
    used[v]=true;
    for(int i=0;i<G[v].size();i++)
    {
        int u=G[v][i],w=match[u];
        if(w<0||!used[w]&&dfs(w))
        {
            match[v]=u;
            match[u]=v;
            return true;
        }
    }
    return false;
}

int bipartite_matching()
{
    int res=0;
    memset(match,-1,sizeof(match));
    for(int v=1;v<=V;v++)
    {
        if(match[v]<0)
        {
            memset(used,0,sizeof(used));
            if(dfs(v))
            {
                res++;
            }
        }
    }
    return res;
}

int main()
{
    while(cin>>n>>k)
    {
        V=n*2;
        for(int i=0;i<k;i++)
        {
            int r,c;
            scanf("%d%d",&r,&c);
            add_edge(r,n+c);
        }
        cout<<bipartite_matching()<<endl;
    }
    return 0;
}

poj3041(二分匹配简单题)

时间: 2024-10-03 00:18:22

poj3041(二分匹配简单题)的相关文章

一些二分匹配的题

/*poj1469简单的二分匹配*/ #include<stdio.h> #include<string.h> int map[1005][1005],vis[2000],match[2000]; int n,m; int dfs(int u) { int i,j; for(i=1;i<=n;i++)//根据课 { if(!vis[i]&&map[u][i]) { vis[i]=1; if(match[i]==-1||dfs(match[i])) { matc

UVALive 6525 Attacking rooks 二分匹配 经典题

题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4536">点击打开链接 题意: 给定n*n的棋盘, 能够在'.'上摆 象棋中的车(X是墙壁) 使得随意两个车都不能互相攻击到 问:最多能摆多少个车. 思路: 二分匹配 1.若没有X.那么做法就是 X点集为行,Y点集为列,对于图上的每一个点所在的行和列(x,y) 建一条边 x->y 2.有了X,那么对于每一个点所在的上方能接触到的X必须

COURSES 赤裸裸的二分匹配大水题

COURSES 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include &l

poj 2239 Selecting Courses(二分匹配简单模板)

http://poj.org/problem?id=2239 这里要处理的是构图问题p (1 <= p <= 7), q (1 <= q <= 12)分别表示第i门课在一周的第p天的第q节课上 其中二分图的X集合里表示课程i,那么我们要解决的就是Y集合了 将第i门课在一周的第p天的第q节课上进行编号,这样Y集合就是 上课时间的编号了 #include<stdio.h> #include<string.h> #include<math.h> #in

UVA5874 Social Holidaying 二分匹配

二分匹配简单题,看懂题意,建图比较重要. #include<stdio.h> #include<string.h> #define maxn 1100 int map[maxn][maxn]; int a[maxn],b[maxn],match[maxn],vis[maxn]; int n,m; void makemap() { int i,j,k; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { for(k=1;k<=m;k++)

hdu 2255 二分图带权匹配 模板题

模板+注解在 http://blog.csdn.net/u011026968/article/details/38276945 hdu 2255 代码: //KM×î´ó×îСƥÅä #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define INF 0x0fffffff const int MAXN

HDU 2119 Matrix 简单二分匹配

行做x集,列做y集,1就给该行该列连一条边,输出最大匹配边即可 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<set> using namespace std; #define N 105 int lef[N], pn;//lef[v]表示Y集的点v 当前连接的点 , pn为x点集的

HDU2063(二分匹配入门模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063 过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9322    Accepted Submission(s): 4108 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求

hdu-4185.loiol_skimming(简单二分匹配模型)

1 /************************************************************************* 2 > File Name: hdu-4185.oil_skimming.cpp 3 > Author: CruelKing 4 > Mail: [email protected] 5 > Created Time: 2019年09月03日 星期二 09时12分12秒 6 本题思路:简单分析过后就可以知道如果一点a被另一个点b匹配