zoukankan      html  css  js  c++  java
  • POJ3041轰炸行星(匈牙利算法 最小覆盖点集)

    Asteroids
    Time Limit: 1000MS Memory Limit: 65536K
    Total Submissions: 25232 Accepted: 13625

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

    题目传送门:点击打开链接

    题目大意:给你一个n*n的矩阵,和m个行星的坐标,你有一种武器,每一次使用可以把一行或者一列的行星清空,现在要你使用最少的次数,将行星清空,输出最少次数。

    思路:因为这道题的分类是匈牙利算法,最大匹配数,所以我知道不是贪心,(其实想一下,贪心是错的)。但是头秃没思路啊,后来知道了匈牙利算法的一个重要结论,最小覆盖点集=最大匹配数,什么是最小覆盖点集呢?就是能把一副二分图所有的边都有一端点存在于这个集合中(就是把每条边都碰到了),这个点可以出现在二分图的任意一边,数量等于最大匹配数,这个结论我是现学现卖的所以大家可以自己百度证明。(与此相像的还有一个定理,是最小覆盖边集=顶点数-最大匹配数。)

    利用这个结论,我们可以想,我们是要选择行和列,把所有的行星都炸掉,和这个结论中利用点,覆盖所有的边思路是一样的,所以这道题的二分图点集就是,左边是行,右边是列,然后用坐标来表示连接关系,比如存在(2,3)这个点,那就是第二行和第三列建边。最后匈牙利算法求一下就可以了。

    这里再推荐一个匈牙利算法讲的很好的博客:点击打开链接

    最后上代码,都不需要注释啦嘿嘿。

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<queue>
    #include<iostream>
    #include<algorithm>
    #define MAXN 10100
    #define INF 0x7fffffff
    #define max(a,b) a>b?a:b
    #define min(a,b) a>b?b:a
    using namespace std;
    const int maxn=600;
    int g[maxn][maxn];
    int girl[maxn],used[maxn];
    int n,m;
    bool find(int x){
    	for(int i=1;i<=n;i++){
    		if(g[x][i]&&used[i]==0){
    			used[i]=1;
    			if(girl[i]==0||find(girl[i])){
    				girl[i]=x;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    int main(){
    	cin>>n>>m;
    	while(m--){
    		int c,r;
    		scanf("%d%d",&c,&r);
    		g[c][r]=1;
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++){
    		memset(used,0,sizeof(used));
    		if(find(i))ans++;
    	}
    	printf("%d
    ",ans);
    }

    ——愿为泰山而不骄 qq850874665~~
  • 相关阅读:
    Yii2 在模块modules间跳转时,url自动加模块名
    PHP 变量的间接引用(将某一字符串转化为变量)
    windows鼠标悬停任务栏 延迟时间 修改
    dede 常用标签和调用方法汇总
    dedecms ---m站功能基础详解
    apache 2.2 和2.4 目录权限访问设置的区别
    apache httpd.conf 配置局域网访问
    ajax php 点击加载更多
    dede调用当前栏目名 、dede sql
    dede 添加 栏目缩略图
  • 原文地址:https://www.cnblogs.com/mountaink/p/9536731.html
Copyright © 2011-2022 走看看