zoukankan      html  css  js  c++  java
  • [COGS 2583]南极科考旅行

    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 行包含一个浮点数,表示小美需要走的最短距离,保留两位小数。

    【样例输入】

    4
    1 1
    2 3
    4 1
    3 2
    

    【样例输出】

     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+10;
      4 const int MAXE=2e5+10;
      5 const double INF=1e10;
      6 const int INFI=0x3F3F3F3F;
      7 const double EPSILON=1e-5;
      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=1;i<=n;i++){
     49         scanf("%lf%lf",&N[i].x,&N[i].y);
     50     }
     51     std::sort(N+1,N+1+n);
     52     for(int i=2;i<n;i++){
     53         Insert(0,i<<1,0,1);
     54         Insert(i<<1|1,1,0,1);
     55     }
     56     Insert(0,1<<1,0,2);
     57     Insert(n<<1|1,1,0,2);
     58     v=n*2+2;
     59     for(int i=1;i<=n;i++){
     60         for(int j=i+1;j<=n;j++){
     61             Insert(i<<1,j<<1|1,EucDis(N[i],N[j]),1);
     62         }
     63     }
     64     printf("%.2f
    ",Dinic(0,1));
     65     return 0;
     66 }
     67 
     68 double Dinic(int s,int t){
     69     double ans=0;
     70     while(SPFA(s,t)){
     71         memset(vis,0,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==0)
     79         return flow;
     80     int tmp=flow;
     81     int k;
     82     vis[s]=true;
     83     for(Edge* i=head[s];i!=NULL&&tmp>0;i=i->next){
     84         if(i->flow>0&&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=0;i<v;i++)
     96         dis[i]=INF;
     97     memset(vis,0,sizeof(vis));
     98     std::queue<int> q;
     99     q.push(s);
    100     vis[s]=true;
    101     dis[s]=0;
    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>0&&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+1;
    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=0;
    132     top->rev=top-1;
    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

    日常图包

  • 相关阅读:
    【转载】Linux下各文件夹的含义和用途
    【转载】Linux 通过mount -o loop 配置本地.iso镜像为yum源(yum仓库)
    Fedora 和 RedHat 以及 SUSE 中 YUM 工具的使用
    【转】下载对应内核版本的asmlib
    【转】VMWare vCenter 6.0安装配置
    【转】在VMware中为Linux系统安装VM-Tools的详解教程
    【转】虚拟化(五):vsphere高可用群集与容错
    html拼接时onclick事件传递json对象
    bootstrap table 解析写死的json.并且把进度条放进列中。
    开发规范实体和值对象
  • 原文地址:https://www.cnblogs.com/rvalue/p/8036487.html
Copyright © 2011-2022 走看看