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/ ...
随机推荐
- win7家庭版升级旗舰版
点“开始”——在“所有程序”点"Windows Anytime Update"——点“输入升级密钥”,然后就出现一个密钥框,输入一个旗舰版的密钥,确定就行了,10分钟左右就升级好了 ...
- XC应用系列作品(Android应用)
XC系列应用,如真题园手机客户端1.1等应用已经分别在 360手机助手.腾讯应用宝.百度手机助手.小米应用商店.豌豆荚.应用汇.木蚂蚁等安卓市场平台上线了! 本页面的系列应用是本人的开发的一Andro ...
- IT技能栈
C++.JAVA.Objective-C 基本数据类型,集合类如字符串数组字典,自定义数据对象 内存布局,编译运行期的变化 语言特性 输入输出流,文件流,序列化 多线程,并发控制,线程池,锁 网络编程 ...
- Migration of ASP.NET app from IIS6 to IIS7 (7.5)
For many of us familiar problem. You developing applications under IIS6 and you're about to move the ...
- 使用Windows的NAT功能
使用管理员权限打开命令行控制台. 端口映射相关命令 查看当前机器的端口代理表: netsh interface portproxy show all C:\WINDOWS\system32>ne ...
- redis安装与使用
linux: 1.下载redis 下载redis: 可以在redis的官网下载 : http://redis.io/ 也可以去谷歌的code下载: http://code.google.com/p/r ...
- Spring文件上传出错:java.lang.ClassCastException: org.apache.catalina.connector.Request
java.lang.ClassCastException: org.apache.catalina.connector.RequestFacade cannot be cast to org.spri ...
- Android多屏幕适配
转载:http://mikewang.blog.51cto.com/3826268/865304 问题: 测试时,发现应用在不同的显示器上显示效果不同(部分文本不能显示完全),自然想到屏幕适配的问题. ...
- 关于 ORA - 01861 文字与格式字符串不匹配问题(oracle存储过程)
一般问题(TO_DATE 和 TO_CHAR 两种格式互换)比如: 只要转化下格式就OK ,这里就不详细解释这两种格式的用法了! 今天把之前做好的模块拿到当地实习,不管怎么测 ,连续测试了好几个存储过 ...
- HTML基础(2) 格式标签 文本标签
格式标签: 1.<p></p> 用来显示段落 2.<br> 控制换行 3.<nobr> </nobr> 防止浏览器将过长内容自动换行显示 ...