Occupy Cities
hdu4606:http://acm.hdu.edu.cn/showproblem.php?pid=4606
题意:在一个二维坐标系中,有n个城市,坐标给出来了,然后有p个士兵要去占领这n个城市,但是路上有m个路障,都是线段,士兵不能越过路障前进。
每个士兵都有相同容量大小的一个干粮袋,每到一个城市他就能补充满自己的干粮袋。中途走路时走一个单位长度就消耗一个单位的干粮。
现在问的是这些个干粮袋最小的容量是多少,前提是保证p个士兵能占领完这n个城市,城市被占领顺序也是题目给好的,必须遵守。
题解:这一题是一道很好的综合题。首先一点,就是求出任意两个城市的最短距离。这个也是我今天学到的知识。我们可以把障碍的端点当做2个点,如果城市i和城市j之间没有障碍的话,那么i,j之间的距离就可以直接算出。如果有障碍的话,就只能绕过障碍的端点来求。怎么求呢?只要把端点当做路径上的点就可以了,然后用floyd过一遍即可。这里,要用到判断两条线段是否相交的。然后可以联想到的是最小点覆盖。但是这里的是最小点覆盖小于p都是满足的。所以接下来可以二分枚举长度,找到最小额满足条件的长度。用到二分以及二分图的最大匹配。因为最小点覆盖==点数--二分图的最大匹配。还有一个就序列,这也是要考虑。这里只哎哟我们建图的时候,让前面的序列指向后面的序列就可以了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
const double inf=1000000000.0;
int n,m,p;
int seq[],cy[];
double g[][];
bool key[][],visit[];
struct point{
double x,y;
}dian[];
struct Node{
point a;
point b;
}xian[];
double dis(int a,int b){
return sqrt((dian[a].x-dian[b].x)*(dian[a].x-dian[b].x)+(dian[a].y-dian[b].y)*(dian[a].y-dian[b].y)); }
double Cross( point a, point b, point o){
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}
bool IsIntersect( Node u, Node v){
return (Cross(v.a, u.b, u.a) * Cross(u.b, v.b, u.a) > ) &&
(Cross(u.a, v.b, v.a) * Cross(v.b, u.b, v.a) > ) &&
(max(u.a.x, u.b.x) > min(v.a.x, v.b.x)) &&
(max(v.a.x, v.b.x) > min(u.a.x, u.b.x)) &&
(max(u.a.y, u.b.y) > min(v.a.y, v.b.y)) &&
(max(v.a.y, v.b.y) > min(u.a.y, u.b.y));
} bool judge(int a,int b){
for(int i=;i<=m;i++){
if((a+-n)/==i&&(b+-n)/==i)continue;
Node temp;temp.a=dian[a];temp.b=dian[b];
if(IsIntersect(temp,xian[i]))
return false;
}
return true;
}
int path(int u){
for(int i=;i<=n;i++){
if(!visit[i]&&key[u][i]){
visit[i]=;
if(cy[i]==-||path(cy[i])){
cy[i]=u;
return ;
}
}
}
return ;
}
int maxmatch(){
memset(cy,-,sizeof(cy));
int res=;
for(int i=;i<=n;i++){
memset(visit,,sizeof(visit));
res+=path(i);
}
return res;
}
bool task(double mid){
memset(key,,sizeof(key));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if(g[i][j]<=mid&&seq[i]<seq[j])
key[i][j]=;
}
int as=maxmatch();
if(n-as<=p)return true;
else return false;
} double solve(){
double l=,r=inf,ans=;
while(abs(l-r)>0.0000001){
double mid=(l+r)/;
if(task(mid)){
ans=mid;
r=mid;
}
else
l=mid;
}
return ans;
}
int temp;
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
scanf("%d%d%d",&n,&m,&p);
memset(g,,sizeof(g));
for(int i=;i<=n;i++){
scanf("%lf%lf",&dian[i].x,&dian[i].y);
}
for(int i=;i<=m;i++){
scanf("%lf %lf",&xian[i].a.x,&xian[i].a.y);
dian[i*+n-].x=xian[i].a.x;
dian[i*+n-].y=xian[i].a.y;
scanf("%lf %lf",&xian[i].b.x,&xian[i].b.y);
dian[i*+n].x=xian[i].b.x;
dian[i*+n].y=xian[i].b.y;
}
memset(seq,,sizeof(seq));
for(int i=;i<=n;i++){
scanf("%d",&temp);
seq[temp]=i;
}
for(int i=;i<=n+*m;i++){
for(int j=;j<=n+*m;j++){
if(j==i)continue;
if(judge(i,j)){
g[i][j]=dis(i,j);
}
else
g[i][j]=inf;
}
g[i][i]=inf;
}
for(int k=;k<=n+*m;k++)
for(int i=;i<=n+*m;i++)
for(int j=;j<=n+*m;j++)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
double ans=;
ans=solve();
printf("%.2f\n",ans);
}
}
Occupy Cities的更多相关文章
- 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
http://acm.hdu.edu.cn/showproblem.php?pid=4606 两点之间如果有线段相隔的话,他们的最短路就需要经过线段的端点 把所有线段的端点也加入点数组中,求任意两个点 ...
- HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)
题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...
- HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题目:给出n个城市需要去占领,有m条线段是障碍物, ...
- 【 2013 Multi-University Training Contest 1 】
HDU 4602 Partition f[i]表示和为i的方案数.已知f[i]=2i-1. dp[i]表示和为i,k有多少个.那么dp[i]=dp[1]+dp[2]+...+dp[i-1]+f[i-k ...
- 2013 Multi-University Training Contest 1
HDU-4605 Magic Ball Game 题意:给定一颗以1为根的数,每个节点要么有两个孩子节点,要么没有孩子,每个节点有一个重量,现在从节点1往下放置一个小球,根据小球和节点的重量的不同球落 ...
- Connect the Cities[HDU3371]
Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- codeforces 613D:Kingdom and its Cities
Description Meanwhile, the kingdom of K is getting ready for the marriage of the King's daughter. Ho ...
- CF449B Jzzhu and Cities (最短路)
CF449B CF450D http://codeforces.com/contest/450/problem/D http://codeforces.com/contest/449/problem/ ...
随机推荐
- 深度剖析:CDN内容分发网络技术原理--转载
1.前言 Internet的高速发展,给人们的工作和生活带来了极大的便利,对Internet的服务品质和访问速度要求越来越高,虽然带宽不断增加,用户数量也在不断增加,受Web服务器的负荷和传输距离等因 ...
- PropertyGrid仿VS的属性事件窗口
效果图:. 首先我们去重写一下PropertyGrid: internal class MyPropertyGrid : System.Windows.Forms.PropertyGrid { pri ...
- float与double的范围和精度(摘录)
什么是浮点数在计算机系统的发展过程中,曾经提出过多种方法表达实数.典型的比如相对于浮点数的定点数(Fixed Point Number).在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置. ...
- Linux平台的boost安装全解
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...
- System Operations on AWS - Lab 4W - Monitoring (Windows)
创建Web Server实例,配置CloudWatch来收集Web Server的系统日志,当错误登录次数达到设定值时触发报警 1. 创建Web Server 1.1 创建一个IAM策略 1.2 创建 ...
- Linux下安装Python pip
在Python环境下,pip提供类似yum一样的下载方式,比easy_install方便的多. 1.下载get-pip.py wget https://bootstrap.pypa.io/get-pi ...
- 动态树 Link-Cut Trees
动态树 动态树问题, 即要求我们维护一个由若干棵子结点无序的有根树组成的森林. 要求这个数据结构支持对树的分割.合并,对某个点到它的根的路径的某些操作,以及对某个点的子树进行的某些操作. 在这里我们考 ...
- 第一篇:web之前端之html
前端之html 前端之html 本节内容 前端概述 html结构 标签探秘 <!DOCTYPE html>标签 head标签 body标签 1.前端概述 一个web服务的组成分为前端和 ...
- Navicat 看历史执行SQL
Navicat可以通过这个框口看手动操作所执行的代码操作
- js获取UserControl (<uc1>)控件ID
ASPX: <table> <tr> <td> <uc1:uccalendar id="ucXudaxia" runat="se ...