Occupy Cities

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 509    Accepted Submission(s): 125

Problem Description
The Star Wars is coming to an end as the Apple Planet is beaten by the Banana Planet. Captain Chen, the glorious leader of the Army of Banana Planet, has drawn up a plan to occupy all the cities on the Apple Planet. The Army of Banana Planet totally has P soldiers, and thus, Captain Chen can only conduct at most P soldiers to occupy the cities.
The cities on the planet can be regarded as points on a 2D plane. What's more, there are some barriers on the planet, which can be seen as segments on the plane. When a soldier moves from city to city, he's not allowed to cross or touch the barriers. However, the soldiers are smart enough to go along the shortest paths between cities.
But these soldiers are just soldiers, whereupon they also need food to replenish their energy. A soldier needs one unit of food to move one unit of distance forward. Fortunately, all the cities have sufficient food supplies. When a soldier steps in a city, he will fill up his food bag. Invaders as they are, the soldiers will burn up all the food after filling his bag. And thus, each city can supply only one soldier.
When a soldier steps in a city, this city is occupied by the Army of Banana Planet immediately. Soldiers can also just pass by a city but not step in. In this case, this city is not occupied yet, and the food in the city would not be burned.
Captain Chen has an occupying schedule for his soldiers. If city A is arranged before city B on the schedule, city A must be occupied before city B. All the soldiers will strictly follow this schedule. During the occupying process, soldiers can be air-dropped to any positions on the plane as needed. After a soldier lands on the ground, he can only move on foot, and replenish his energy by the food in his bag. Note that their bags are full of food initially, and all bags have the same volume for soldiers.
You, the logistics minister of the army, are required to help the Captain to cut down the cost and determine the minimal volume of all P soldiers' food bags to finish occupying. All the requirements above should be fulfilled for sure.
 
Input
The first line contains an integer T(T≤50), indictaing the number of test cases.
Each test case begins with three integers n(0<n≤100), m(0≤m≤100) and p(0<p≤100), which respectively denotes the number of cities, barriers and soldiers.
The following n lines describe the cities' coordinates (x_i,y_i).
The next m lines, each with two pairs of integers (sxi,syi) and (exi,eyi), describe the two endpoints of each barrier.
The last line of each test case consists of n integers, describing the occupying schedule in order.
All the coordinates range from -10000 to 10000, and cities are labeled from 1 to n. You may assume that any two barriers will not have common points and cities will not be built on barriers.
 
Output
For each test case, output the minimal volume of soldiers' food bag, in accuracy of two decimal places. The answers should be printed one per line.
 
Sample Input
2

2 1 1
0 0
2 0
1 1 1 -1
2 1

4 2 2
0 1
5 1
8 0
1 -1
0 0 2 0
6 0 6 3
1 2 3 4

 
Sample Output
2.83
3.41

Hint

For the second sample case, the best strategy is:
step 1: air-drop soldier 1 to city 1, city 1 occupied;
step 2: air-drop soldier 2 to city 2, city 2 occupied;
step 3: soldier 2 moves from city 2 to city 3, city 3 occupied, and 3.41 units of food needed;
step 4: soldier 1 moves from city 1 to city 4, city 4 occupied, and 2.41 units food needed.
Therefore, the minimal volume of bags is 3.41.

 
Source
 
Recommend
liuyiding
 

题目都很长。

p个士兵,占领n个城市,其中有m个线段阻隔,不能从线段穿过去。

占领有顺序。

每个士兵有个背包,背包一开始是满的,占领一个以后可以补充满。

一个城市只能占领一次。

问背包最少可以提供多长距离的粮食。

先最短路,求得两两之间的最短距离,其中要判断线段和线段相交。

然后是二分,求最小路径覆盖。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <vector>
using namespace std; const double eps = 1e-;
int sgn(double x)
{
if(fabs(x) < eps)return ;
if(x < )return -;
else return ;
}
struct Point
{
double x,y;
Point(double _x = ,double _y = )
{
x = _x; y = _y;
}
Point operator -(const Point &b)const
{
return Point(x-b.x,y-b.y);
}
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
void input()
{
scanf("%lf%lf",&x,&y);
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s; e = _e;
}
void input()
{
s.input();
e.input();
}
};
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
bool inter(Line l1,Line l2)
{
return
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) < &&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) < ;
} const int MAXN = ;
Point p[MAXN];
Line line[MAXN];
const double INF = 100000000.0;
double dis[MAXN][MAXN];
int n,m,P; int b[MAXN]; int uN,vN;
struct Edge
{
int to,next;
}edge[MAXN*MAXN];
int head[MAXN];
int tot;
void addedge(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void init()
{
tot = ;
memset(head,-,sizeof(head));
}
int linker[MAXN];
bool used[MAXN];
bool dfs(int u)
{
for(int i = head[u]; i!= -;i = edge[i].next)
{
int v = edge[i].to;
if(!used[v])
{
used[v] = true;
if(linker[v]==- || dfs(linker[v]))
{
linker[v] = u;
return true;
}
}
} return false;
}
int hungary()
{
int res = ;
memset(linker,-,sizeof(linker));
for(int u = ;u < uN;u ++)
{
memset(used,false,sizeof(used));
if(dfs(u))res++;
}
return res;
}
bool check(double d)
{
uN = vN = n;
init();
for(int i = ;i < n;i++)
for(int j = i+;j < n;j++)
if(dis[b[i]][b[j]] < d + eps)
addedge(b[i],b[j]);
if(n - hungary() <= P)return true;
else return false;
}
double solve()
{
double l = , r = 100000.0;
double ans;
while(r-l >= eps)
{
double mid = (l+r)/;
if(check(mid))
{
ans = mid;
r = mid - eps;
}
else l = mid + eps;
}
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&P);
for(int i = ;i < n;i++)
p[i].input();
int t = n;
for(int i = ;i < m;i++)
{
line[i].input();
p[n+*i] = line[i].s;
p[n+*i+] = line[i].e;
}
for(int i = ;i < n+*m;i++)
for(int j = ;j < n+*m;j++)
{
if(i == j)
{
dis[i][j] = ;
continue;
}
bool flag = false;
for(int k = ;k < m;k++)
if(inter(line[k],Line(p[i],p[j])))
{
flag = true;
break;
}
if(flag)dis[i][j] = 1e20;
else dis[i][j] = dist(p[i],p[j]);
}
for(int k = ;k < n+*m;k++)
for(int i = ;i < n+*m;i++)
for(int j = ;j < n+*m;j++)
dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i = ;i < n;i++)
{
scanf("%d",&b[i]);
b[i]--;
}
printf("%.2lf\n",solve());
}
return ;
}

HDU 4606 Occupy Cities (计算几何+最短路+二分+最小路径覆盖)的更多相关文章

  1. HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题目:给出n个城市需要去占领,有m条线段是障碍物, ...

  2. HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)

    题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...

  3. 【网络流24题】No.4 魔术球问题 (二分+最小路径覆盖)

    [题意] 假设有 n 根柱子, 现要按下述规则在这 n 根柱子中依次放入编号为 1, 2, 3, ¼的球.( 1)每次只能在某根柱子的最上面放球.( 2)在同一根柱子中,任何 2 个相邻球的编号之和为 ...

  4. hdu 4606 Occupy Cities

    http://acm.hdu.edu.cn/showproblem.php?pid=4606 两点之间如果有线段相隔的话,他们的最短路就需要经过线段的端点 把所有线段的端点也加入点数组中,求任意两个点 ...

  5. poj 3216 Repairing Company(最短路Floyd + 最小路径覆盖 + 构图)

    http://poj.org/problem?id=3216 Repairing Company Time Limit: 1000MS   Memory Limit: 131072K Total Su ...

  6. HDU 3861 The King’s Problem 强连通分量 最小路径覆盖

    先找出强连通分量缩点,然后就是最小路径覆盖. 构造一个二分图,把每个点\(i\)拆成两个点\(X_i,Y_i\). 对于原图中的边\(u \to v\),在二分图添加一条边\(X_u \to Y_v\ ...

  7. hdu 4606 简单计算几何+floyd+最小路径覆盖

    思路:将所有的直线的两个端点和城市混在一起,将能直接到达的两个点连线,求一次floyd最短路径.二分枚举bag容量,然后按给的要先后占领的城市由前向后,把能到一步到达的建一条边.然后求一次最小路径覆盖 ...

  8. HDU 3861--The King’s Problem【scc缩点构图 &amp;&amp; 二分匹配求最小路径覆盖】

    The King's Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. HDU 3861.The King’s Problem 强联通分量+最小路径覆盖

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. Flume的安装,配置及使用

    1,上传jar包 2,解压 3,改名 4,更改配置文件 将template文件重镜像 root@Ubuntu-1:/usr/local/apache-flume/conf# cat flume-env ...

  2. 【洛谷 P1070】道路游戏 (DP)

    题目链接 这题还是很好想的,看到\(90%\)的数据点时,我就知道要用\(n^3\)的算法(最后10分就算了吧) 然后,数据水,直接暴力\(n^3\)卡过了. 显然是道DP. 设\(f[i]\)表示第 ...

  3. [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法

    Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...

  4. aiohttp/asyncio 小例子和解释

    #!/usr/bin/env python # encoding: utf-8 import aiohttp import asyncio import time # 通过async def定义的函数 ...

  5. EF选择Mysql数据源

    EF添加ADO.NET实体模型处直接选择Mysql数据源 最近想到EF是连接多数据库的orm框架,于是就想测试下.查了一堆网上资料后,测试连接mysql成功.步骤如下: 1.在你项目Model层中nu ...

  6. PHPstorm创建注释模版

    /** * $NAME$ * @param * @return * @since $DATE$ * @author Name */$END$ /** * xxxx -­- Controller – 类 ...

  7. 基于iscroll实现下拉和上拉刷新

    在原生APP的开发中,有一个常见的功能,就是下拉刷新的功能,这个想必大家都是知道的,但是原生APP的开发,有一个很大的问题就是,你每次更新一些功能,就要用户重新下载一次版本,尤其是在iOS系统中,新版 ...

  8. docker run 的背后的故事(zz)

    当利用docker run来创建并启动容器的时候,docker后台标准的操作包括: 1.检查本地是否存在指定的镜像,不存在就从公有仓库下载. 当我依瓢画葫芦的运行: sudo docker run - ...

  9. hdu 1669(二分图多重匹配)

    Jamie's Contact Groups Time Limit: 15000/7000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/ ...

  10. 胖AP与瘦AP区别

    一.胖AP组网方案 1.漫游问题 用户从一个胖AP的覆盖区域走到另一个胖AP的覆盖区域,会重新连接信号强的一个胖AP,重新进行认证,重新获取IP地址,存在断网现象: 2.无法保证WLAN的安全性 为了 ...