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 ...
 
随机推荐
- Ant——ant的使用
			
---------------------------------------------------------------------------------------------------- ...
 - 论文阅读之:Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network
			
Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network 2016.10.23 摘要: ...
 - JavaScript 字符串转日期
			
一.将字符串装换为日期 var date= new Date(Date.parse(strTime.replace(/-/g, "/"))); //转换成Data();
 - post 与 get 在转码的区别
			
前端输入中文的时候,后端post通过 String text = getRequest().getParameter("text");可以正常拿到中文, 但是通过get的时候就会出 ...
 - Tcpdump非常实用的抓包12实例
			
1.过滤主机---------------------------------------------------------------- - 抓取所有经过 eth1,目的或源地址是 192.168 ...
 - Logstash安装及部署
			
安装及部署 一.环境配置 操作系统:Cent OS 7 Logstash版本:2.1.1.tar.gz JDK版本:1.7.0_51 SSH Secure Shell版本:XShell 5 二.操作过 ...
 - 使用C#对SQLLite进行操作
			
1.数据库连接(常用连接方法,示例) 1). 添加引用: System.Data.SQLite.DLL .2). 打开或创建数据库文件: SQLiteConnection.CreateFile(fil ...
 - 封装实现一个自己的tabbar
			
实现效果:
 - php include require
			
includ和require都是把其他页面加载当前页面,不过不同的是,require如果没有找到,或者所包含的页面里面有错误就不会往下执行了 <?php include 'form.php'; ...
 - eclipse中没有R文件
			
换了台电脑,把eclipse安装上去,很久没用,最近用了一下.发现R文件无法生成.试了各种方法. Project-->Clean:从其他的项目中,复制一个R.java过来:检查语法:勾选上了Pr ...