hdu 4606 Occupy Cities
http://acm.hdu.edu.cn/showproblem.php?pid=4606
两点之间如果有线段相隔的话,他们的最短路就需要经过线段的端点
把所有线段的端点也加入点数组中,求任意两个点的距离(可达的话,没有其他线段阻挡)
然后对所有的点进行floyd 可以求出任意两点的最短路
然后二分所需容量 根据容量和要求的顺序进行建图,求最小覆盖路径(匈牙利算法)
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#include<queue>
#include<stdexcept>
#include<bitset>
#include<cassert>
#include<deque>
#include<numeric> //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; typedef long long ll;
typedef unsigned int uint;
typedef pair<int,int> pp;
const double eps=1e-9;
const int INF=0x3f3f3f3f;
const ll MOD=1000000007;
const int N=510;
double x[N],y[N];
double dist[N][N];
int schedule[N];
bool visited[N];
bool link[N][N];
int f[N];
int lr(double x1,double y1,double x2,double y2)
{
double tmp=x1*y2-x2*y1;
if(abs(tmp)<eps)
return 0;
if(tmp>=eps)
return 1;
return -1;
}
bool dfs(int x,int n)
{
for(int i=x+1;i<=n;++i)
if(link[x][i]&&!visited[i])
{
visited[i]=true;
if(f[i]==-1||dfs(f[i],n))
{
f[i]=x;
return true;
}
}
return false;
}
int needSoldier(int n,double d)
{
memset(link,false,sizeof(link));
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
if(d-dist[schedule[i]][schedule[j]]>=eps)
link[i][j]=true;
memset(f,-1,sizeof(f));
int sum=0;
for(int i=1;i<=n;++i)
{
memset(visited,false,sizeof(visited));
if(dfs(i,n))
++sum;
}
return (n-sum);
}
double bar(int l,int r,int n,int ln)
{
for(int i=n+1;i<=ln;i=i+2)
{
double x1=x[r]-x[l];
double y1=y[r]-y[l];
double x2=x[i]-x[l];
double y2=y[i]-y[l];
int k1=lr(x1,y1,x2,y2);
x2=x[i+1]-x[l];
y2=y[i+1]-y[l];
int k2=lr(x1,y1,x2,y2);
if(k1==0||k2==0||k1==k2)
continue;
x1=x[i+1]-x[i];
y1=y[i+1]-y[i];
x2=x[l]-x[i];
y2=y[l]-y[i];
k1=lr(x1,y1,x2,y2);
x2=x[r]-x[i];
y2=y[r]-y[i];
k2=lr(x1,y1,x2,y2);
if(k1==0||k2==0||k1==k2)
continue;
return INF;
}
return sqrt((x[r]-x[l])*(x[r]-x[l])+(y[r]-y[l])*(y[r]-y[l]));
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("1007.in","r",stdin);
//freopen("my.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
int n,m,p;
scanf("%d %d %d",&n,&m,&p);
for(int i=1;i<=n;++i)
scanf("%lf %lf",&x[i],&y[i]);
int ln=n;
while(m--)
{
++ln;
scanf("%lf %lf",&x[ln],&y[ln]);
++ln;
scanf("%lf %lf",&x[ln],&y[ln]);
}
for(int i=1;i<=n;++i)
scanf("%d",&schedule[i]);
for(int i=1;i<=ln;++i)
for(int j=i;j<=ln;++j)
{
if(i==j) dist[i][j]=0.0;
else
dist[i][j]=dist[j][i]=bar(i,j,n,ln);
}
for(int l=1;l<=ln;++l)
for(int i=1;i<=ln;++i)
for(int j=1;j<=ln;++j)
if(dist[i][j]>dist[i][l]+dist[l][j])
dist[i][j]=dist[i][l]+dist[l][j];
/*
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
cout<<dist[i][j]<<" ";cout<<endl;
}*/
double l=0.0,r=1000000.0;
double ep=1e-6;
while(abs(r-l)>ep)
{
double mid=(l+r)/2;
if(needSoldier(n,mid)<=p)
r=mid;
else
l=mid;
}
printf("%.2lf\n",r);
}
return 0;
}
hdu 4606 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://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题目:给出n个城市需要去占领,有m条线段是障碍物, ...
- HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)
题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...
- Occupy Cities
hdu4606:http://acm.hdu.edu.cn/showproblem.php?pid=4606 题意:在一个二维坐标系中,有n个城市,坐标给出来了,然后有p个士兵要去占领这n个城市,但是 ...
- hdu 4606 简单计算几何+floyd+最小路径覆盖
思路:将所有的直线的两个端点和城市混在一起,将能直接到达的两个点连线,求一次floyd最短路径.二分枚举bag容量,然后按给的要先后占领的城市由前向后,把能到一步到达的建一条边.然后求一次最小路径覆盖 ...
- hdu 2874Connections between cities LCA
题目链接 给n个城市, m条边, q个询问, 每个询问, 输出城市a和b的最短距离, 如果不联通, 输出not connected. 用并查集判联通, 如果不连通, 那么两个联通块之间加一条权值很大的 ...
- 【 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 ...
- hdu 3371 Connect the Cities(最小生成树)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3371 984ms风险飘过~~~ /************************************ ...
- 2013 Multi-University Training Contest 1
HDU-4605 Magic Ball Game 题意:给定一颗以1为根的数,每个节点要么有两个孩子节点,要么没有孩子,每个节点有一个重量,现在从节点1往下放置一个小球,根据小球和节点的重量的不同球落 ...
随机推荐
- mysql 倒引号
1.在mysql中,保留字不能作为表名,字段名等用处,如下:mysql> alter table student add column desc varchar(16) after name;1 ...
- Myeclipse优化篇
1 . window-preferences-MyEclipse Enterprise Workbench-Maven4MyEclipse-Maven ,将 Maven JDK 改为电脑上安装的 JD ...
- JS---------->数组练习!
var arr = [4, 0, 7, 9, 0, 0, 2, 6, 0, 3, 1, 0]; 要求将数组中的0项去掉,将不为0的值存入一个新的数组,生成新的数组 <!doctype htm ...
- AutoCompleteTextView控件的使用
public class MainActivity extends Activity { //[0]声明AutoCompleteTextView要显示的数据 private static final ...
- Linux的中断 & 中断和异常的区别
参考 http://www.yesky.com/20010813/192117.shtml 结构化程序设计思想认为:程序 = 数据结构 + 算法.数据结构体现了整个系统的构架,所以数据结构通常都是代码 ...
- Nginx基本配置备忘
原文:http://www.open-open.com/lib/view/open1482477873078.html Nginx 配置 在了解具体的Nginx配置项之前我们需要对于Nginx配置文件 ...
- openfire过滤脏话插件,控制消息是否发送
参考:http://myopenfire.com/article/getarticle/9 package com.myopenfire.plugin; import java.io.File; im ...
- Spring集成JPA提示Not an managed type
在做Spring与JPA集成时,出现问题如下: Caused by: java.lang.IllegalArgumentException: Not an managed type: class co ...
- 转:为什么C++中空类和空结构体大小为1?
参考:http://www.spongeliu.com/260.html 为什么C++中空类和空结构体大小为1? On November 17, 2010, in C语言, 语言学习, by spon ...
- Yum常用命令及Yum中文手册
转自:http://blog.csdn.net/huangbiao86/article/details/6646471 Yum配置文件位于/etc/yum.conf和/etc/yum.repos.d/ ...