LightOJ 1313 - Protect the Mines(凸包)
| Time Limit: 2 second(s) | Memory Limit: 32 MB |
You are a rich man, and recently you bought a place which contains some mines of rare metals like gold, platinum etc. As the metals are rare, their cost is also so high. So, you need to protect them from thieves. But things are not as easy as it looks.
So, you called a bunch of engineers to make some wired fences around the mines. As they were just engineers (not problem solvers!), they drilled some holes in random places. The idea was to put some pillars on the drilled holes and after that some wires should be set in the pillars, and finally electrifying the wires would be the completion. And of course, each mine should be surrounded by a fence. Wires should be placed between two pillars, in straight lines. The engineers drilled the holes in positions such that some of the mines might not be covered by any fences.
However, your plan is that, you can put some guards in mines that are not surrounded by any fence. To guard a single mine, it would cost G dollars, and a pillar cost is P dollars. As you are a rich man, the costs of wires are too small that they can be ignored. So, you want to put guards in some mines and surround some other mines by fences, but you want to find the optimal cost to protect all the mines. The fences may or may not be convex.
In bird's eye view, we can get the following figure (fig 1) for sample 1. There are seven pre-drilled holes (marked as circles), and six mine positions (marked as squares). The straight lines show the wires and the closed regions form the fences. The figure shows one of the optimal solutions.
Fig 1
So, you have to find the minimum cost for executing your plan.
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case starts with a line containing four integers N (3 ≤ N ≤ 100), M (1 ≤ M ≤ 100), G (1000 ≤ G ≤ 2000) and P (100 ≤ P ≤ 200), N denotes the number of pre-drilled holes, and M denotes the number of mines. This line is followed by N lines that describe the positions of the holes, and then by M lines that describe the positions of the mines. All positions are given as pairs of integers x y on one line (0 ≤ x, y ≤ 1000). You can assume that no two positions (of holes and mines) coincide and that no three positions are collinear.
Output
For each case, print the case number and the minimum cost to protect all the mines.
Sample Input |
Output for Sample Input |
|
2 7 6 1000 100 0 0 20 0 1 10 39 10 1 20 39 20 20 30 3 9 37 9 3 21 37 21 18 24 50 24 4 3 1500 100 0 0 0 10 10 0 10 10 5 4 4 1 8 6 |
Case 1: 1600 Case 2: 300 |
首先根据题目意思,
一个mine如果可以被holes覆盖的话,肯定在一个三角形里面,因为G比P至少大10倍,所以最佳策略就是把可以覆盖的全部覆盖掉,其余的加士兵上去。
首先求一下凸包,把凸包内部的所有mines都找出来。
然后搞floyed, 就是看最少几步可以形成环,把所有都包括进来,
debug了好久,太坑了,以后写几何要慎重了。
/* ***********************************************
Author :kuangbin
Created Time :2014/4/22 19:32:10
File Name :E:\2014ACM\专题学习\计算几何\凸包\LightOJ1313.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; // 计算几何int 版,注意如果超int,相应的要改为long long
const int maxp = ;
struct Point
{
int x,y;
Point(){}
Point(int _x,int _y)
{
x = _x; y = _y;
}
void input()
{
scanf("%d%d",&x,&y);
}
bool operator == (Point b)const
{
return x == b.x && y == b.y;
}
bool operator < (Point b)const
{
return x == b.x ? y < b.y : x < b.x;
}
Point operator - (const Point &b)const
{
return Point(x-b.x,y-b.y);
}
int operator ^ (const Point &b)const
{
return x*b.y - y*b.x;
}
int operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
double len2()
{
return x*x + y*y;
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;
e = _e;
}
//点和直线关系
//1 在左侧
//2 在右侧
//3 在直线上
int relation(Point p)
{
int c = (p-s)^(e-s);
if(c < )return ;
else if(c > )return ;
else return ;
}
bool pointonseg(Point p)
{
return ((p-s)^(e-s)) == && ((p-s)*(p-e)) <= ;
}
};
struct polygon
{
int n;
Point p[maxp];
void input(int _n)
{
n = _n;
for(int i = ;i < n;i++)
p[i].input();
}
struct cmp
{
Point p;
cmp(const Point &p0){p = p0;}
bool operator()(const Point &aa,const Point &bb)
{
Point a = aa, b = bb;
int d = (a-p)^(b-p);
if(d == )
return (a-p).len2() < (b-p).len2();
return d > ;
}
};
void norm()
{
Point mi = p[];
for(int i = ;i < n;i++)
mi = min(mi,p[i]);
sort(p,p+n,cmp(mi));
}
void getconvex(polygon &convex)
{
sort(p,p+n);
convex.n = n;
for(int i = ;i < min(n,);i++)
{
convex.p[i] = p[i];
}
if(n <= )return;
int &top = convex.n;
top = ;
for(int i = ;i < n;i++)
{
while(top && ((convex.p[top]-p[i])^(convex.p[top-]-p[i]))<=)
top--;
convex.p[++top] = p[i];
}
int temp = top;
convex.p[++top] = p[n-];
for(int i = n-;i >= ;i--)
{
while(top != temp && ((convex.p[top]-p[i])^(convex.p[top-]-p[i]))<=)
top--;
convex.p[++top] = p[i];
}
convex.norm();
}
//判断点和任意多边形的关系
//3 点上
//2 边上
//1 内部
//0 外部
int relation(Point q)
{
for(int i = ;i < n;i++)
{
if(p[i] == q)return ;
}
for(int i = ;i < n;i++)
{
if(Line(p[i],p[(i+)%n]).pointonseg(q))return ;
}
int cnt = ;
for(int i = ;i < n;i++)
{
int j = (i+)%n;
int k = ((q-p[j])^(p[i]-p[j]));
int u = (p[i].y-q.y);
int v = (p[j].y-q.y);
if(k > && u < && v >= )cnt++;
if(k < && v < && u >= )cnt--;
}
return cnt != ;
}
};
Point mines[maxp];
Point mines2[maxp];
int cnt;
polygon A,B;
bool check(Line v)
{
for(int i = ;i < cnt;i++)
if(v.relation(mines2[i]) != )
return false;
return true;
}
int a[][];
int b[][];
int c[][];
int solve(polygon A)
{
int n = A.n;
memset(a,,sizeof(a));
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
if(i != j && check(Line(A.p[i],A.p[j])))
a[i][j] = ;
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
b[i][j] = a[i][j];
for(int s = ;s <= n;s++)
{
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
c[i][j] = b[i][j];
memset(b,,sizeof(b));
for(int i = ;i < n;i++)
for(int j = ;j < n;j++)
for(int k = ; k < n;k++)
if(c[i][k] && a[k][j])
b[i][j] = ;
for(int i = ;i < n;i++)
if(b[i][i])
return s;
}
return -;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n,m,g,p;
int iCase = ;
scanf("%d",&T);
while(T--)
{
iCase++;
scanf("%d%d%d%d",&n,&m,&g,&p);
A.input(n);
for(int i = ;i < m;i++)
mines[i].input();
A.getconvex(B);
cnt = ;
//找出在凸包内的
for(int i = ;i < m;i++)
if(B.relation(mines[i]) == )
mines2[cnt++] = mines[i];
int ans1 = (m-cnt)*g;
int tmp = ;
if(cnt)tmp = solve(A);
printf("Case %d: %d\n",iCase,ans1 + tmp*p);
}
return ;
}
LightOJ 1313 - Protect the Mines(凸包)的更多相关文章
- LightOJ 1203--Guarding Bananas(二维凸包+内角计算)
1203 - Guarding Bananas PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 M ...
- LightOJ 1239 - Convex Fence 凸包周长
LINK 题意:类似POJ的宫殿围墙那道,只不过这道题数据稍微强了一点,有共线的情况 思路:求凸包周长加一个圆周长 /** @Date : 2017-07-20 15:46:44 * @FileNam ...
- LightOJ 1203 Guarding Bananas (凸包最小顶角)
题目链接:LightOJ 1203 Problem Description Once there was a lazy monkey in a forest. But he loved banana ...
- UVa 109 - SCUD Busters(凸包计算)
题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...
- LightOj1203 - Guarding Bananas(凸包求多边形中的最小角)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1203 题意:给你一个点集,求凸包中最小的角:模板题,但是刚开始的时候模板带错了,错的我 ...
- HDU 4946 Area of Mushroom 凸包
链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...
- POJ 1873 The Fortified Forest [凸包 枚举]
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6400 Accepted: 1 ...
- poj 1873 凸包+枚举
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6198 Accepted: 1 ...
- poj1873(枚举+凸包)
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7291 Accepted: 2 ...
随机推荐
- poj3461 字符串匹配 熟悉kmp算法第一题
题意: 计算一个字符串在另一个字符串中出现的次数. #include<cstdio> #include<cstring> #include<algorithm> ...
- 知识积累:关于Memory
仅清除页面缓存(PageCache)# sync; echo 1 > /proc/sys/vm/drop_caches清除目录项和inode# sync; echo 2 > /proc/s ...
- python string module
String模块中的常量 >>> import string >>> string.digits ' >>> string.letters 'ab ...
- C++多重继承带来的问题
首先上图,咱们看图说话! 橙色表示变量,使用private修饰. 如图,假设Person类的变量name只能通过input方法来输入. 那么继承自Person的Student及Teacher类中s ...
- MongoDB快速上手
1. MongoDB简介 MongoDB是一个跨平台的基于Key_Value键值对形式保存数据的NoSQL文档类型数据库. NoSQL(not only sql)数据库,泛指非关系型数据库. 1.1 ...
- 如何成为一名合格甚至优秀的个人草根站长(转载自ChinaZ)
这章本来不想写来的,后来琢磨琢磨还是废话一下吧.主要是想说下现在草根站长的状态和如何成为一名合格的甚至优秀的草站站长. 伟大的草根站长们,在某些媒体的超级忽悠下全来到网络上淘金来了,有在校的大学生,有 ...
- 转来的。。。 关于return 的一些事情
转来的 http://blog.csdn.net/haiwil/article/details/6691854/ 一般的来说,函数是可以返回局部变量的. 局部变量的作用域只在函数内部,在函数返回后,局 ...
- web.config
参数上传和文件上传大小限制调整,参数上传最大2097151 <system.web> <httpRuntime requestValidationMode="2.0&quo ...
- 第五周PSP
16号 类别c 内容c 开始时间s 结束e 中断I 净时间T GUI 学习QT视频 20:00 21:42 20m 82m 17号 类别c 内容c 开始时间s 结束e 中断I 净时间T GUI 学习Q ...
- osmdroid启程
osmdroid一个牛逼的开源地图引擎,从今天开始好好研究一下~