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


PROBLEM SETTER: JANE ALAM JAN

首先根据题目意思,

一个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(凸包)的更多相关文章

  1. LightOJ 1203--Guarding Bananas(二维凸包+内角计算)

    1203 - Guarding Bananas    PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 M ...

  2. LightOJ 1239 - Convex Fence 凸包周长

    LINK 题意:类似POJ的宫殿围墙那道,只不过这道题数据稍微强了一点,有共线的情况 思路:求凸包周长加一个圆周长 /** @Date : 2017-07-20 15:46:44 * @FileNam ...

  3. LightOJ 1203 Guarding Bananas (凸包最小顶角)

    题目链接:LightOJ 1203 Problem Description Once there was a lazy monkey in a forest. But he loved banana ...

  4. UVa 109 - SCUD Busters(凸包计算)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  5. LightOj1203 - Guarding Bananas(凸包求多边形中的最小角)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1203 题意:给你一个点集,求凸包中最小的角:模板题,但是刚开始的时候模板带错了,错的我 ...

  6. HDU 4946 Area of Mushroom 凸包

    链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...

  7. POJ 1873 The Fortified Forest [凸包 枚举]

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6400   Accepted: 1 ...

  8. poj 1873 凸包+枚举

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6198   Accepted: 1 ...

  9. poj1873(枚举+凸包)

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 7291   Accepted: 2 ...

随机推荐

  1. Codeforces Round #341 Div.2 A. Wet Shark and Odd and Even

    题意是得到最大的偶数和 解决办法很简单 排个序 取和 如果是奇数就减去最小的奇数 #include <cstdio> #include <cmath> #include < ...

  2. 列表框QListWidget类

    QListWidget类也是GUI中常用的类,它从QListView下派生: class Q_GUI_EXPORT QListWidget : public QListView { Q_OBJECT ...

  3. hpp头文件与h头文件的区别

    hpp,其实质就是将.cpp的实现代码混入.h头文件当中,定义与实现都包含在同一文件,则该类的调用者只需要include该hpp文件即可,无需再将cpp加入到project中进行编译.而实现代码将直接 ...

  4. Windows下运行python脚本报错“ImportError: No Module named ...”的解决方法

    之前遇到一个问题,在Pycharm或IPython之类的IDE上运行脚本正常,但是直接运行或cmd命令行运行的时候报了模块未能找到的错误--ImportError: No Module named . ...

  5. 为什么在注册和注销的时候intent要改成隐式调用

    显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件. 隐式意图: ...

  6. RH LINUX5.5 RAW绑定

    ****************ORACLE 11G RAC***********************Disk /dev/sdb: 2147 MB, 2147483648 bytes67 head ...

  7. 使用php添加定时任务

    1.  php执行外部命令的函数:       system(),exec(),passthru()      注意点:     1.调用的路径,相对路径有时候不是很靠谱.           sys ...

  8. JAVA 新手问题: Request 编码编译出错,Unhandled exception type UnsupportedEncodingException

    新手: 编写如下代码 private void Exec(HttpServletRequest Req,HttpServletResponse Response) //throws ServletEx ...

  9. jdbc操作数据库

    JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC. 学习JD ...

  10. Java分布式Socket监控项目思考

    内容说明 一项课程作业Java编写Socket长连接监控分布式终端,并将终端状态写入数据库供前端查询 基础:c++/Posix/APUE/Mysql&sqlite 核心内容:Socket/线程 ...