题目大意:给出田鼠数目与地洞数目,每个地洞可以容纳一只田鼠,给出田鼠坐标与地洞坐标,田鼠速度与逃逸最大时间,求出最少被抓住田鼠数。
解题策略:简单二部图,答案 = 田鼠总数-(田鼠——地洞)二部图最大匹配数,邻接表实现。
/*
UVA 10080 Gopher II
AC by J_Dark
ON 2013/4/19
Time 0.044s
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int gopherNum, holesNum, timeLimit, speed, ans;
struct XY{
double x, y;
XY(double a=0, double b=0) { x = a; y = b;}
double pathCompute(XY A){
return sqrt(pow(A.x-x, 2.0) + pow(A.y-y, 2.0));
}
};
vector< vector<int> > reachedHoles;
vector<XY> G; //田鼠
vector<XY> H; //地洞
vector<int> pairHG; //存放匹配边
vector<bool> visited; //增广路径判定标记
//寻找增光路径
bool findPath(int g){
for(int i=0; i<reachedHoles[g].size(); i++){
int tempH = reachedHoles[g][i];
if(!visited[tempH]){
visited[tempH] = true;
if( pairHG[tempH] == -1 || findPath(pairHG[tempH]) ){ //发现未匹配边
pairHG[tempH] = g; //修改匹配信息
return true;
}
}
}
return false; //未找到匹配边
}
//匈牙利算法 DFS求最大匹配
void Compute(){
int matching = 0;
for(int g=0; g<gopherNum; g++){
visited.clear();
visited.resize(holesNum);
if(findPath(g))
matching++;
}
//最少被抓住田鼠数 = 田鼠总数 - 最大匹配数
cout << gopherNum - matching << endl;
}
void Input(){
double x, y;
G.clear();
H.clear();
for(int i=0; i<gopherNum; i++){
cin >> x >> y;
G.push_back(XY(x, y));
}
for(int i=0; i<holesNum; i++){
cin >> x >> y;
H.push_back(XY(x, y));
}
reachedHoles.clear();
pairHG.clear();
for(int h=0; h<holesNum; h++) pairHG.push_back(-1); //初始化未匹配
}
void Solve(){
const double eps = 1e-10;
vector<int> holes;
for(int g=0; g<G.size(); g++){
holes.clear();
for(int h=0; h<H.size(); h++){
if(double(timeLimit*speed) - G[g].pathCompute(H[h]) > eps)
holes.push_back(h);
}
reachedHoles.push_back(holes);
}
}
/
int main(){
while(cin >> gopherNum >> holesNum >> timeLimit >> speed)
{
Input();
Solve();
Compute();
}
//system("pause");
return 0;
}