HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目:给出n个城市需要去占领,有m条线段是障碍物,有p个士兵可以用。占领城市有个先后顺序,每个士兵有个背包,占领城市之后,仅能补给一次背包。问背包容量最少是多少,可以用这P个士兵完成任务,起点任意 。
http://acm.hdu.edu.cn/showproblem.php?pid=4606
首先:枚举所有顶点,求一下距离,判断是否与线段相交。然后 floyd预处理最短路
之后是二分答案,判断是否可达
根据占领的先后顺序建边,根据二分的值判断不需要补给是否能够到达。
之后便是判断最小路径覆盖数是否小于等于P。
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 505;
const int M = 3000000;
const int INF = 100000;
const double eps = 1e-7;
inline int dcmp(double d){
return d < -eps? -1 : d > eps;
}
inline double sqr(double d){
return d * d;
}
struct Point {
double x, y;
Point (){}
Point (double _x,double _y):x(_x),y(_y){}
inline bool operator == (const Point &p)const {
return (dcmp(x - p.x) == 0 && dcmp(y - p.y) == 0);
}
inline Point operator - (const Point &p)const {
return Point(x - p.x,y - p.y);
}
inline double operator * (const Point &p)const {
return x * p.y - y * p.x;
}
inline double operator / (const Point &p)const {
return x * p.x + y * p.y;
}
inline double Distance(Point p){
return sqrt(sqr(p.x - x) + sqr(p.y - y));
}
void input(){
scanf ("%lf %lf", &x, &y);
}
}p[N];
struct Line{
Point a,b;
void input(){
a.input();
b.input();
}
Line(){}
Line(Point _a,Point _b):a(_a),b(_b){}
inline bool operator == (const Line &l) const{
return (a == l.a && b == l.b) || (a == l.b && b == l.a);
}
inline double operator * (const Point &p)const {
return (b - a) * (p - a);
}
inline double operator / (const Point &p)const {
return (p - a) / (p - b);
}
inline int SegCrossSeg(const Line &v){
int d1 = dcmp((*this) * v.a);
int d2 = dcmp((*this) * v.b);
int d3 = dcmp(v * a);
int d4 = dcmp(v * b);
if((d1 ^ d2) == -2 && (d3 ^ d4) == -2) return 2;
return ((d1 == 0 && dcmp((*this) / v.a) <= 0)
||(d2 == 0 && dcmp((*this) / v.b) <= 0)
||(d3 == 0 && dcmp(v / a) <= 0)
||(d4 == 0 && dcmp(v / b) <= 0) );
}
}l[N];
int n , m , K , seq[N];
int match[N], vis[N];
double dist[N][N];
int tot , start[N];
struct Edge {
int v, next;
}e[N * N];
void _add (int u , int v) {
e[tot].v = v;
e[tot].next = start[u];
start[u] = tot ++;
}
bool dfs (int u) {
for (int i = start[u] ; i != -1 ; i = e[i].next) {
int v = e[i].v;
if (! vis[v]) {
vis[v] = 1;
if(match[v] == -1 || dfs(match[v])) {
match[v] = u;
return true;
}
}
}
return false;
}
int hungry () {
int ans = 0;
memset (match , -1, sizeof(match)) ;
for (int i = 1 ; i <= n ; i ++) {
memset (vis , 0 , sizeof(vis));
if (dfs(i)) ans ++;
}
return ans;
}
bool check (double mid) {
tot = 0 ;
memset (start , -1 , sizeof(start));
for (int i =1 ; i <= n ; i ++) {
for (int j = i + 1 ; j <= n ; j ++) {
if(dist[seq[i]][seq[j]] <= mid)
_add (seq[i] , seq[j] + n);
}
}
return n - hungry() <= K;
}
double solve(){
double l = 0 , r = INF;
double ans = -1;
int cnt = 50;
while(cnt --){
double mid = (l + r) * 0.5;
if(check(mid)){
ans = mid;
r = mid;
}
else l = mid;
}
return ans;
}
int main(){
int t;
scanf ("%d", &t);
while (t --){
scanf ("%d%d%d", &n, &m, &K);
for (int i = 1 ; i <= n ; i ++){
p[i].input();
}
for (int i = 1 ; i <= m ; i ++){
l[i].input();
p[n + (i - 1) * 2 + 1] = l[i].a;
p[n + i * 2] = l[i].b;
}
for (int i = 1 ; i <= n + m * 2 ; i ++){
for (int j = 1 ; j <= n + m * 2 ; j ++){
if(i == j) dist[i][j] = 0.0;
else {
bool flag = false;
for (int k = 1 ; k <= m ; k ++){
if(l[k] == Line(p[i] , p[j])) continue;
if (l[k].SegCrossSeg(Line(p[i] , p[j])) == 2) {
flag = true;
break ;
}
}
if(flag) dist[i][j] = 1e9;
else dist[i][j] = p[i].Distance(p[j]);
}
}
}
for(int i = 1;i <= n;i ++){
scanf("%d",&seq[i]);
}
for (int k = 1 ; k <= n + m * 2 ; k ++) {
for (int i = 1 ; i <= n + m * 2 ; i ++) {
for (int j = 1 ; j <= n + m * 2 ;j ++ ){
dist[i][j] = fmin(dist[i][j] , dist[i][k] + dist[k][j]);
}
}
}
double ans = solve();
printf("%.2f\n",ans);
}
return 0;
}
HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)的更多相关文章
- Delivering Goods UVALive - 7986(最短路+最小路径覆盖)
Delivering Goods UVALive - 7986(最短路+最小路径覆盖) 题意: 给一张n个点m条边的有向带权图,给出C个关键点,问沿着最短路径走,从0最少需要出发多少次才能能覆盖这些关 ...
- HDU 4606 Occupy Cities (计算几何+最短路+二分+最小路径覆盖)
Occupy Cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)
题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...
- (hdu step 6.3.3)Air Raid(最小路径覆盖:求用最少边把全部的顶点都覆盖)
题目: Air Raid Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- hdu 4606 Occupy Cities
http://acm.hdu.edu.cn/showproblem.php?pid=4606 两点之间如果有线段相隔的话,他们的最短路就需要经过线段的端点 把所有线段的端点也加入点数组中,求任意两个点 ...
- HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...
- Air Raid---hdu1151(最小路径覆盖)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1151 最小路径覆盖 == 顶点数 - 最大匹配. #include<stdio.h> #i ...
- hdu 4606 简单计算几何+floyd+最小路径覆盖
思路:将所有的直线的两个端点和城市混在一起,将能直接到达的两个点连线,求一次floyd最短路径.二分枚举bag容量,然后按给的要先后占领的城市由前向后,把能到一步到达的建一条边.然后求一次最小路径覆盖 ...
- HDU 3861.The King’s Problem 强联通分量+最小路径覆盖
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
随机推荐
- android 休眠唤醒机制分析(三) — suspend
本文转自:http://blog.csdn.net/g_salamander/article/details/7988340 前面我们分析了休眠的第一个阶段即浅度休眠,现在我们继续看休眠的第二个阶段 ...
- SIM卡读卡器的研究与设计
SIM卡(Subscriber Identity Module).即用户识别模块,是一张符合GSM规范的"智慧卡".SIM卡可以插入任何一部符合GSM规范的移动电话中," ...
- 【HDOJ】5017 Ellipsoid
简单地模拟退火. /* 5017 */ #include <cstdio> #include <cstring> #include <cstdlib> #inclu ...
- BZOJ [JSOI2008]魔兽地图DotR
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1243 Solved: 532[Submit][S ...
- HBase Java API入门
概括 1. 创建.删除及启用禁用表.添加列等都需用到HBaseAdmin,另外需要注意删除,添加列等操作都需要禁用表 2. 表中添加数据,查询等都是和HTable相关,如果是多线程的情况下注意用HTa ...
- F - Power Network - poj 1459(简单最大流)
题目大意:题目说了一大堆,其实都是废话......让人有些不知所云,其实就是给了一些电厂,和一些消费点,然后里面有一些路线什么的,求出消费点可以最多消费的电量是多少. 输入大意: 分析:懂了题意就是一 ...
- C++ —— 类模板的分离式编译
目录 对于C++中类模板的分离式编译的认识 具体的实例 1.对于C++中类模板的分离式编译的认识 为什么C++编译器不能支持对模板的分离式编译(博文链接) 主要内容:编译器编译的一般工作原理.对模版的 ...
- angularjs改变路由时控制器每次都执行两次
原因如下: 代码里面也初始化了控制器 模板配置了一个控制器
- kubernetes组件
kubernetes组件 @(马克飞象)[k8s] 组件 kubernetes除了必备的dns和网络组件外,官方推出大量的cluster-monitoring,dashboard,fluentd-el ...
- Object -C NSNumber -- 笔记
// // main.m // NSNumber // // Created by facial on 24/8/15. // Copyright (c) 2015 facial_huo. A ...