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 ...
随机推荐
- github 如何合并不同分支
From: http://stackoverflow.com/questions/1123344/merging-between-forks-in-github 1. 添加remote origina ...
- hmtl的标签属性
html标签< <marquee>...</marquee>普通卷动 <marquee behavior=slide>...</marquee>滑 ...
- CC3000 SPI接口编程介绍
CC3000 SPI 操作: CC3000的SPI 是基于五根线CLCK,CSn,IRQ,MISO,MOSI:通信模式如下图: CLCK:时钟频率0-26M从主机到从机,提供SPI接口时钟 CSn:低 ...
- Apache Shiro系列教程之三:Shiro的结构
Shiro的设计目标是简化应用的安全管理工作.软件通常是以用户为基础设计的.也就是说,我们经常是根据用户是怎样和我们的软件交互的来设计相关的用户接口.比如,你可能会说"如果是已经登录的用户与 ...
- ThinkPad E440 加内存后导致开不了机
上周五新买的ThinkPad E440,原装内存是4G DDR3 1600Hz,明显不够用,于是在京东上买了一根南亚易胜的4G DDR3 1600Hz.安装之后正常开机,明显感觉速度快了很多.可是用了 ...
- Hibernate getCurrentSession()和openSession()的区别
通过getCurrentSession()创建的Session会绑定到当前线程上:openSession()不会. 通过getCurrentSession()获取Session,首先是从当前上下文中寻 ...
- [家里蹲大学数学杂志]第013期2010年西安偏微分方程暑期班试题---NSE,非线性椭圆,平均曲率流,非线性守恒律,拟微分算子
Navier-Stokes equations 1 Let $\omega$ be a domain in $\bbR^3$, complement of a compact set $\mathca ...
- 【Python与机器学习】:利用Keras进行多类分类
多类分类问题本质上可以分解为多个二分类问题,而解决二分类问题的方法有很多.这里我们利用Keras机器学习框架中的ANN(artificial neural network)来解决多分类问题.这里我们采 ...
- MEF load plugin from directory
var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(".")); var ...
- HTML页面嵌入视频和JS控制切换视频的问题
文章摘自:http://www.cnblogs.com/jorton/archive/2012/03/19/vidio_in_site.html 首先,在页面中嵌入视频的HTML代码为: 1 < ...