2583. 南极科考旅行

★★   输入文件:BitonicTour.in   输出文件:BitonicTour.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

小美要在南极进行科考,现在她要规划一下科考的路线。

地图上有 N 个地点,小美要从这 N 个地点中 x 坐标最小的地点 A,走到 x 坐标最大的地点 B,然后再走回地点 A。

请设计路线,使得小美可以考察所有的地点,并且在从 A 到 B 的路程中,考察的地点的 x 坐标总是上升的,在从 B 到 A 的过程中,考察的地点的 x 坐标总是下降的。

求小美所需要走的最短距离(欧几里得距离)。

【输入格式】

输入共 N+1 行。

第 1 行包含 1 个正整数 N,表示地图上共有 N 个地点。

第 1 +(1) 至 1 +(N) 行,每行包含 2 个正整数 x, y,表示其中 1 个地点的坐标。

【输出格式】

输出共 1 行。

第 1 行包含一个浮点数,表示小美需要走的最短距离,保留两位小数。

【样例输入】

  1. 4
  2. 1 1
  3. 2 3
  4. 4 1
  5. 3 2

【样例输出】

  1. 8.06

【数据范围及约定】

对于前 20% 测试数据

3 <= N <= 6

1 <= x <= 20, 1 <= y <= 20

对于后 80% 测试数据

3 <= N <= 300

1 <= x <= 10000, 1 <= y <= 10000

对于全部测试点,保证每个点坐标的 x 值互不相同

【来源】

Bitonic Tour

题解

乍一看好像一脸 $DP$ 的样子...这种要走一个来回的情形似乎是之前的某个叫做小烈上菜的题...

然而居然出现在了网络流专题里...

行吧网络流就网络流...一开始感觉不会有费用流就开始构最大流(最小割)的图然而直接 $GG$ ...然后意识到是费用流...

woc我不会打费用流啊QAQ

$dbw$ 强行教学一波 $zkw$ 网络流...打完板子开始构图w

首先肯定是要按横坐标排序, 然后我们发现一去一回的方向并没有什么卵用, 找到一个环和找到两条路径是等价的. 这样我们可以发现, 每个结点都必须选择两条边, 其中 $x$ 最小的结点两条都是出边, 最大的结点两条都是入边, 其他结点一条入边一条出边, 这样的话我们可以得到这样的构图:

其中较粗的边容量为2, 较细的边容量为1, $s$ 连出的边和连向 $t$ 的边费用为 $0$ , 实际结点间边的距离即为欧几里得距离.

写 $zkw$ 网络流的话有一个坑点: 由于增广时要判断某条边是否在最短路上, 但是现在费用是一个实数, 所以会有精度问题, 直接使用  dis[s]+i->dis==dis[i->to]  判定的话会炸精度死循环, 这点需要注意OwO

参考代码

GitHub

  1. #include <bits/stdc++.h>
  2.  
  3. const int MAXV=1e3+;
  4. const int MAXE=2e5+;
  5. const double INF=1e10;
  6. const int INFI=0x3F3F3F3F;
  7. const double EPSILON=1e-;
  8.  
  9. struct Edge{
  10. int from;
  11. int to;
  12. int flow;
  13. double dis;
  14. Edge* rev;
  15. Edge* next;
  16. };
  17. Edge E[MAXE];
  18. Edge* head[MAXV];
  19. Edge* top=E;
  20.  
  21. struct Node{
  22. double x;
  23. double y;
  24. bool friend operator<(const Node& a,const Node& b){
  25. return a.x<b.x;
  26. }
  27. };
  28. Node N[MAXV];
  29.  
  30. int n;
  31. int v;
  32. bool vis[MAXV];
  33. double dis[MAXV];
  34.  
  35. double Sqr(double);
  36. bool SPFA(int,int);
  37. int DFS(int,int,int);
  38. double Dinic(int,int);
  39. void Insert(int,int,double,int);
  40. double EucDis(const Node&,const Node&);
  41.  
  42. int main(){
  43. #ifndef ASC_LOCAL
  44. freopen("BitonicTour.in","r",stdin);
  45. freopen("BitonicTour.out","w",stdout);
  46. #endif
  47. scanf("%d",&n);
  48. for(int i=;i<=n;i++){
  49. scanf("%lf%lf",&N[i].x,&N[i].y);
  50. }
  51. std::sort(N+,N++n);
  52. for(int i=;i<n;i++){
  53. Insert(,i<<,,);
  54. Insert(i<<|,,,);
  55. }
  56. Insert(,<<,,);
  57. Insert(n<<|,,,);
  58. v=n*+;
  59. for(int i=;i<=n;i++){
  60. for(int j=i+;j<=n;j++){
  61. Insert(i<<,j<<|,EucDis(N[i],N[j]),);
  62. }
  63. }
  64. printf("%.2f\n",Dinic(,));
  65. return ;
  66. }
  67.  
  68. double Dinic(int s,int t){
  69. double ans=;
  70. while(SPFA(s,t)){
  71. memset(vis,,sizeof(vis));
  72. ans+=DFS(s,INFI,t)*dis[t];
  73. }
  74. return ans;
  75. }
  76.  
  77. int DFS(int s,int flow,int t){
  78. if(s==t||flow==)
  79. return flow;
  80. int tmp=flow;
  81. int k;
  82. vis[s]=true;
  83. for(Edge* i=head[s];i!=NULL&&tmp>;i=i->next){
  84. if(i->flow>&&fabs(dis[i->from]+i->dis-dis[i->to])<EPSILON&&!vis[i->to]){
  85. k=DFS(i->to,std::min(tmp,i->flow),t);
  86. tmp-=k;
  87. i->flow-=k;
  88. i->rev->flow+=k;
  89. }
  90. }
  91. return flow-tmp;
  92. }
  93.  
  94. bool SPFA(int s,int t){
  95. for(int i=;i<v;i++)
  96. dis[i]=INF;
  97. memset(vis,,sizeof(vis));
  98. std::queue<int> q;
  99. q.push(s);
  100. vis[s]=true;
  101. dis[s]=;
  102. while(!q.empty()){
  103. s=q.front();
  104. vis[s]=false;
  105. q.pop();
  106. for(Edge* i=head[s];i!=NULL;i=i->next){
  107. if(i->flow>&&dis[s]+i->dis<dis[i->to]){
  108. dis[i->to]=dis[s]+i->dis;
  109. if(!vis[i->to]){
  110. q.push(i->to);
  111. vis[i->to]=true;
  112. }
  113. }
  114. }
  115. }
  116. return dis[t]<INFI;
  117. }
  118.  
  119. void Insert(int from,int to,double dis,int flow){
  120. top->from=from;
  121. top->to=to;
  122. top->dis=dis;
  123. top->flow=flow;
  124. top->rev=top+;
  125. top->next=head[from];
  126. head[from]=top++;
  127.  
  128. top->from=to;
  129. top->to=from;
  130. top->dis=-dis;
  131. top->flow=;
  132. top->rev=top-;
  133. top->next=head[to];
  134. head[to]=top++;
  135. }
  136.  
  137. inline double EucDis(const Node& a,const Node& b){
  138. return sqrt(Sqr(a.x-b.x)+Sqr(a.y-b.y));
  139. }
  140.  
  141. inline double Sqr(double x){
  142. return x*x;
  143. }

Backup

[COGS 2583]南极科考旅行的更多相关文章

  1. Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)

    1264. [NOIP2012] 开车旅行 ★★☆   输入文件:drive.in   输出文件:drive.out   简单对比时间限制:2 s   内存限制:128 MB [题目描述] 小A 和小 ...

  2. COGS 2. 旅行计划

    2. 旅行计划 ★☆   输入文件:djs.in   输出文件:djs.out   简单对比时间限制:3 s   内存限制:128 MB 过暑假了,阿杜准备出行旅游,他已经查到了某些城市的两两之间的距 ...

  3. cogs 2. 旅行计划 dijkstra+打印路径小技巧

    2. 旅行计划 ★★   输入文件:djs.in   输出文件:djs.out   简单对比时间限制:3 s   内存限制:128 MB [题目描述] 过暑假了,阿杜准备出行旅游,他已经查到了某些城市 ...

  4. cogs 186. [USACO Oct08] 牧场旅行 树链剖分 LCA

    186. [USACO Oct08] 牧场旅行 ★★☆   输入文件:pwalk.in   输出文件:pwalk.out   逐字节对比时间限制:1 s   内存限制:128 MB n个被自然地编号为 ...

  5. 186. [USACO Oct08] 牧场旅行

    186. [USACO Oct08] 牧场旅行(点击转到COGS) 输入文件:pwalk.in   输出文件:pwalk.out 时间限制:1 s   内存限制:128 MB 描述 n个被自然地编号为 ...

  6. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

  7. vijos P1780 【NOIP2012】 开车旅行

    描述 小\(A\)和小\(B\)决定利用假期外出旅行,他们将想去的城市从\(1\)到\(N\)编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市\(i\)的海拔高度为 ...

  8. 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流

    1570: [JSOI2008]Blue Mary的旅行 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 388  Solved: 212[Submit ...

  9. codevs 1036 商务旅行(Targin求LCA)

    传送门 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意 ...

随机推荐

  1. Linux命令之finger

    Linux命令之finger youhaidong@youhaidong-ThinkPad-Edge-E545:~$ finger 程序"finger"尚未安装. 您可以使用以下命 ...

  2. Git资料整理

    一.Git知识 1. Git入门 2. Pro Git 3. 廖雪峰的官方网站 4. 下载地址 二.GitHub 三.Git客户端 1. TortoiseGit 下载地址 Git和TortoiseGi ...

  3. C语言 字符串前加L的意义 如:L“A”

    转自:http://c.biancheng.net/cpp/html/1069.html Unicode或者宽字符都没有改变char数据型态在C中的含义.char继续表示1个字节的储存空间,sizeo ...

  4. Linux性能分析工具top命令详解

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,常用于服务端性能分析. top命令说明 [www.linuxidc.com@linuxidc-t-tomcat-1 ...

  5. python 想搞加密算法吗?快戳这里

    加密算法介绍 一,HASH Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换 ...

  6. spring中的aop的xml配置方式简单实例

    aop,即面向切面编程,面向切面编程的目标就是分离关注点,比如:一个骑士只需要关注守护安全,或者远征,而骑士辉煌一生的事迹由谁来记录和歌颂呢,当然不会是自己了,这个完全可以由诗人去歌颂,比如当骑士出征 ...

  7. IDEA 使用tomcat7-maven-plugin

    使用了这个插件就不需要配置tomcat了,直接用maven去run就行 配置方法:pom里添加:(之所以用tomcat7是因为如果直接用依赖下载很难下载到tomcat8-maven-plugin,详情 ...

  8. error:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long

    问题:mysql中id存的是int(10),java代码中的id为long,转不过去 解决:mysql中的int要是需要转到java中的long,需要选择unsigned这个选项,即if(unsign ...

  9. FJUT2017寒假训练二题解

    A题 题意:让你找出唯一的一个四位数,满足对话时的要求. 思路:因为是4位数,可以直接从1000-9999遍历一遍,判断是否有唯一的数能满足所有条件,如果不是唯一的或者没有满足条件的数就输出Not s ...

  10. MySQL多数据源笔记3-分库分表理论和各种中间件

    一.使用中间件的好处 使用中间件对于主读写分离新增一个从数据库节点来说,可以不用修改代码,达到新增节点数据库而不影响到代码的修改.因为如果不用中间件,那么在代码中自己是先读写分离,如果新增节点, 你进 ...