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 ;
}

最新文章

  1. 如何设置Oracle客户端与服务器的字符集一致
  2. OpenCV2:Mat
  3. Android之界面(布局文件layput)
  4. UWP&amp;WP8.1 重新绘制图片 WriteableBitmap用法 图片转byte[]数组,byte[]数组转图片
  5. MyBatis环境搭建配置文件+入门视频下载
  6. -bash: ./job.sh: /bin/sh^M: bad interpreter: 没有那个文件或目录
  7. .net 配置文件 分析 EntityName 时出错
  8. web进修之—Hibernate 关系映射(3)
  9. javascript 时间函数整理
  10. fatal error c1001 编译器中发生内部错误 OpenMesh6.3
  11. JavaScript中的事件冒泡?事件传播的解释
  12. PowerBuilder编程新思维3:适配(三层架构与GraphQL)
  13. [Spark SQL_1] Spark SQL 配置
  14. ie6下的line-height属性
  15. HTML6的10个高级新特性
  16. Docker使用阿里云镜像加速
  17. Cache与主存地址映像计算例题
  18. STL源码分析-function
  19. Ubuntu 14.10安装simplescalar
  20. 正点原子STM32探索者学习笔记1

热门文章

  1. JavaScript创建对象时常用的设计模式
  2. Python基础(2)_if、for、while流程控制
  3. bzoj3127/3697 [Usaco2013 Open]Yin and Yang
  4. [bzoj2124]等差子序列——线段树+字符串哈希
  5. system32下 exe文件作用
  6. 转: JAVA_SWT常用事件, 和方法
  7. python通过POST提交页面请求
  8. HDU1281(二分图最大匹配,棋盘建图,找关键点)
  9. CTP多点触摸协议【转】
  10. IC卡的传输协议(1)-字符传输协议T=0【转】