题目来源:http://noi.openjudge.cn/ch0403/1538/

1538: Gopher II

总时间限制: 2000ms   内存限制: 65536kB

描述

The gopher family, having averted the canine threat, must face anew predator.

The are n gophers and m gopher holes, each at distinct (x, y) coordinates. Ahawk arrives and if a gopher does not reach a hole in s seconds it isvulnerable to being eaten. A hole can save at most one gopher. All the gophersrun at the same velocity v. The gopher family needs an escape strategy thatminimizes the number of vulnerable gophers.

输入

The input contains several cases. The first line of each casecontains four positive integers less than 100: n, m, s, and v. The next n linesgive the coordinates of the gophers; the following m lines give the coordinatesof the gopher holes. All distances are in metres; all times are in seconds; allvelocities are in metres per second.

输出

Output consists of a single line for each case, giving thenumber of vulnerable gophers.

样例输入

2 2 5 10
1.0 1.0
2.0 2.0
100.0 100.0
20.0 20.0

样例输出

1

来源

Waterloo local 2001.01.27

-----------------------------------------------------

思路

把老鼠看做二分图的左半部,把地洞看做二分图的右半部,如果老鼠能跑进地洞就在老鼠和地洞之间连一条边,问题转化为求二分图的最大匹配。由于需要频繁查找一个节点的相邻节点,故用邻接表存储二分图。

用匈牙利算法求解,其中搜索增广道路用递归深搜实现。数组link表示节点的匹配关系,一个算例只有一个link数组;数组vis表示一次增广道路的求解过程中节点是否被访问,每次增广道路的求解过程vis都不同,需要每次清零

-----------------------------------------------------

代码

#include<iostream>
#include<fstream>
#include<vector>
#include<cstring>
using namespace std;const int GMAX = 105;                  // max(n)
const int NMAX = 205;                  // max(m+n)
int n,m;
int link[NMAX] = {};                   // 一个节点的匹配节点(n+m)个
bool vis[NMAX] = {};                   // 该节点是否被访问过
vector<int> G[NMAX] = {};                // 邻接表
double g_x[GMAX] = {};                 // n只老鼠的坐标
double g_y[GMAX] = {};
double h_x[GMAX] = {};                 // m个地洞的坐标
double h_y[GMAX] = {};int dfs(int i)                           // 求从i开始的增广道路(递归),存在则返回1,不存在返回0
{vector<int> v = G[i];vector<int>::iterator it;int j;for (it=v.begin(); it!=v.end(); it++)         // 遍历i的相邻节点{j = *it;if (!vis[j])                               // 如果j未标记{vis[j] = 1;                              // 把j标记为已访问if (link[j]==-1 || dfs(link[j]))       // 如果j还没有匹配或存在从j出发的增广道路{link[j] = i;                       // 更改j的后继节点为ireturn 1;                          // 找到一条增广道路}}}return 0;                                     // 找不到增广道路
}int main()
{
#ifndef ONLINE_JUDGEifstream fin ("0403_1538.txt");int i,j;double s,v,rad,ans;while (fin >> n >> m){fin >> s >> v;rad = s*v;memset(link, -1, sizeof(link));memset(vis, 0, sizeof(vis));for (i=0; i<NMAX; i++){G[i].clear();}for (i=0; i<n; i++){fin >> g_x[i] >> g_y[i];}for (i=0; i<m; i++){fin >> h_x[i] >> h_y[i];for (j=0; j<n; j++)                 // 求邻接表{if ((h_x[i]-g_x[j])*(h_x[i]-g_x[j])+(h_y[i]-g_y[j])*(h_y[i]-g_y[j])<=rad*rad){G[n+i].push_back(j);G[j].push_back(n+i);}}}ans = 0;for (i=0; i<n; i++){memset(vis, 0, sizeof(vis));     // 每次找增广道路之前把vis数组清零ans += dfs(i);                        // 从i出发是否存在增广道路}cout << (n-ans) << endl;}fin.close();
#endif
#ifdef ONLINE_JUDGEint i,j;double s,v,rad,ans;while (cin >> n >> m){cin >> s >> v;rad = s*v;memset(link, -1, sizeof(link));memset(vis, 0, sizeof(vis));for (i=0; i<NMAX; i++){G[i].clear();}for (i=0; i<n; i++){cin >> g_x[i] >> g_y[i];}for (i=0; i<m; i++){cin >> h_x[i] >> h_y[i];for (j=0; j<n; j++)                   // 求邻接表{if ((h_x[i]-g_x[j])*(h_x[i]-g_x[j])+(h_y[i]-g_y[j])*(h_y[i]-g_y[j])<=rad*rad){G[n+i].push_back(j);G[j].push_back(n+i);}}}ans = 0;for (i=0; i<n; i++){memset(vis, 0, sizeof(vis));     // 每次找增广道路之前把vis数组清零ans += dfs(i);                        // 从i出发是否存在增广道路}cout << (n-ans) << endl;}
#endif
}

NOI 4.3 1538: Gopher II(匈牙利算法求最大匹配)相关推荐

  1. hdu 4160 Dolls 匈牙利算法求最大匹配

    Dolls                                                                               Time Limit: 2000 ...

  2. 【HDU - 2444】The Accomodation of Students(二分图判断 + 匈牙利算法求最大匹配)

    题干: There are a group of students. Some of them may know each other, while others don't. For example ...

  3. 【模板】匈牙利算法 二分图最大匹配题模板

    [任务] 给定一个二分图,用匈牙利算法求这个二分图的最大匹配数. [说明] 求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配. 我们一次枚举左边的点x的所有出边指向的点y, 若y ...

  4. nyoj239 月老的难题 (匈牙利算法,最大匹配,邻接表)

    题目239 题目信息 运行结果 本题排行 讨论区 月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. ...

  5. 用匈牙利算法求二分图的最大匹配

    转载大神的!! 什么是二分图,什么是二分图的最大匹配,这些定义我就不讲了,网上随便都找得到.二分图的最大匹配有两种求法,第一种是最大流(我在此假设读者已有网络流的知识):第二种就是我现在要讲的匈牙利算 ...

  6. 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...

  7. 匈牙利算法 求二分图最大匹配

    匈牙利算法 1. 二分图 二分图: 又称作二部图,是图论中一种特殊模型.设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中每条边所关联的两个顶点 i 和 j 分别属 ...

  8. 浅谈匈牙利算法(二分图最大匹配)

    前置知识 一张图是二分图,当且仅当它的点可以被分成两部分,而这张图上的所有边的两个端点,都分属不同的部分.我们称这两个点集,一个叫左部,一个叫右部.左部中的点叫左部点:右部中的点叫右部点. 一张图的一 ...

  9. POJ-3041 匈牙利算法 二分图最大匹配

    踢以 给出多个点的坐标 有一种攻击 可以把一次干掉同一列的 或者干掉同一行的 求最少的攻击次数 肥西 由于问题是问选取最少的行和列干掉所有的陨石 可以把输入的r和c看成r和c之间有一条连边因为要实现干 ...

  10. 算法题 匈牙利算法 求二分图最大匹配(Python)

    题目: 给定一个二分图,其中左半部包含n1n1个点(编号1~n1n1),右半部包含n2n2个点(编号1~n2n2),二分图共包含m条边. 数据保证任意一条边的两个端点都不可能在同一部分中. 请你求出二 ...

最新文章

  1. 这位图灵奖得主大佬,你可知道?
  2. 页面传值-laber
  3. 每天一道LeetCode-----给定序列中2/3/4个元素的和为target的所有集合,或3个元素的和最接近target的集合
  4. 怎么让存储过程通用化_怎么做分布式存储的面试?
  5. 《计算机科学概论》—第3章3.3节文本表示法
  6. 你的php网页乱码了吗
  7. 顶级赛事,大神现身,速来观战
  8. Exchange Server DAG群集状态部分在线
  9. 支持断点续传的大文件传输协议
  10. java实现日历打印
  11. 家居家装行业人群洞察白皮书.pdf
  12. 运放的基本应用电路-运放电路设计-运算放大器的基本应用电路
  13. 微软zone DNS服务器,DNS 策略概述
  14. python sed awk_观点|awk sed ,一个老派系统管理员的基本素养
  15. JavaSE-day22
  16. 【C++ 科学计算】介绍 C++线性代数和科学计算库 Armadillo
  17. 射频微波芯片设计5:电源旁路电容为何选择0.1uF 10uF?
  18. 单向散列函数概述并基于MD5算法对文件哈希值实时监测
  19. 拉勾教育《产品经理高薪训练营》课程思维导图
  20. 实验三 密码破解技术

热门文章

  1. 计算机的奇迹英语作文,高中英语作文范文:奇迹
  2. 计算机工程好发论文么,计算机工程期刊发表论文有什么要求
  3. kaggel竞赛之员工离职分析
  4. 这些样式表,你都用过么?
  5. PR2018安装及错误处理
  6. 设置电子围栏 高德地图_Android 高德地图的使用, 根据手势拖动绘制电子围栏
  7. java安卓分屏是如何实现的_安卓原生分屏有了,谷歌说:Android Q要实现分屏应用多开...
  8. Openstack Periodic Task
  9. 未能加载文件或程序集 或它的某一个依赖项。试图加载格式不正确的程序。问题解决
  10. “五一”或成疫情来最火爆假期,招行信用卡天天返利助力消费