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往下放置一个小球,根据小球和节点的重量的不同球落 ...
随机推荐
- [转载] 分析Linux内核创建一个新进程的过程
http://blog.luoyuanhang.com/2015/07/27/%E5%88%86%E6%9E%90Linux%E5%86%85%E6%A0%B8%E5%88%9B%E5%BB%BA%E ...
- [转载] C++ 程序员快过来围观:非常实用全面的 C++ 资源
原文: http://codecloud.net/c-plus-plus-resource-2983.html 绝对是c++开发者的福音啊, 必须推荐. 这次的资源涉及到了标准库.Web应用框架.人工 ...
- (三)stm32之串口通信DMA传输完成中断
一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...
- Three.js 3D特效学习
一.Three.js基本介绍 Three.js是JavaScript编写的WebGL第三方库.提供了非常多的3D显示功能.Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场 ...
- 【ufldl tutorial】Convolution and Pooling
卷积的实现: 对于每幅图像,每个filter,首先从W中取出对应的filter: filter = squeeze(W(:,:,filterNum)); 接下来startercode里面将filter ...
- 转:Unicode汉字编码表
转自:http://blog.csdn.net/huangxy10/article/details/10012119 Unicode汉字编码表 1 Unicode编码表 Unicode只有一个字符集 ...
- HTML常用的特殊字符格式
空格: 版权号:©注册商标:®":quot; ':'&:&<:<>:> ©:© «:« ®:® ¯:¯ ¼:¼ (14表示四分之一 ...
- 【bug】“Mat map” opencv全局变量不明确
Mat map= Mat::zeros(WIN_WIDTH, WIN_HIGH, CV_8UC3);//全局变量 int main() { map.setTo(); } Error map 不明确 s ...
- C++ 迭代器介绍 [转摘]
转摘地址为:http://blog.chinaunix.net/uid-20773165-id-1847758.html 迭代器 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围.迭 ...
- LayoutParams使用
LayoutParams继承于Android.View.ViewGroup.LayoutParams. LayoutParams相当于一个Layout的信息包,它封装了Layout的位置. ...