zoukankan      html  css  js  c++  java
  • Dijkstra--The Captain

    *传送

    给定平面上的n个点,定义$(x_1,y_1)$到$(x_2,y_2)$的费用为min(|$x_1$-$x_2$|,|$y_1$-$y_2$|),求从1号点走到n号点的最小费用。

    先给一段证明:给定三个x值,$x_1<x_2<x_3$。可得$x_2-x_1<x_3-x_2<x_3-x_1$,对于最小费用,很明显只有$x_2-x_1$是有用的。对y同理,同时要注意我们不能把$x$和$y$两者混谈。由此我们得到了一个思路,分层图x和y跑一次最短路。

    首先两个$cmp$函数对$n$个点进行的两次排序(注意在之前把点的序号也存下来):

    1 bool cmp1(node a,node b)
    2 {
    3     return a.x<b.x;
    4 }
    5 bool cmp2(node a,node b)
    6 {
    7     return a.y<b.y;
    8 }

    链式前向星构图:

     1 struct edge
     2 {
     3     int next,to,w;
     4 }edge[maxn];
     5 void add(int u,int v,int w)
     6 {
     7     edge[++tot].w=w;
     8     edge[tot].to=v;
     9     edge[tot].next=head[u];
    10     head[u]=tot;
    11 }
    12     sort(a+1,a+n+1,cmp1);
    13     for (int i = 1;i < n;i++)
    14     {
    15         add(a[i].id,a[i+1].id,abs(a[i].x-a[i+1].x));
    16         add(a[i+1].id,a[i].id,abs(a[i].x-a[i+1].x));
    17     }
    18     sort(a+1,a+n+1,cmp2);
    19     for (int i = 1;i < n;i++)
    20     {
    21         add(a[i].id,a[i+1].id,abs(a[i].y-a[i+1].y));
    22         add(a[i+1].id,a[i].id,abs(a[i].y-a[i+1].y));
    23     }

    然后是很标准的dij板子:

     1 void Dijkstra(int S)
     2 {
     3     q.push(make_pair(0,S)); memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[S] = 0;
     4     while(!q.empty())
     5     {
     6         int x = q.top().second; 
     7         q.pop(); 
     8         if(vis[x])
     9             continue; 
    10         vis[x] = 1;
    11         for(int i=head[x];i!=0;i=edge[i].next)
    12         {
    13             int to1=edge[i].to;
    14             if(dis[to1] > dis[x] + edge[i].w)
    15             {
    16                 dis[to1] = dis[x] + edge[i].w ;
    17                 q.push(make_pair(-dis[to1],to1));
    18             }
    19         }
    20     }
    21     return;
    22 }

    完整代码如下:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <queue>
     6 #include <cmath>
     7 using namespace std;
     8 #define ll long long
     9 int n;
    10 const int maxn=1000000;
    11 priority_queue< pair<int ,int > >q;
    12 int dis[maxn],vis[maxn];
    13 int tot=0,head[maxn];
    14 int read(){
    15     int x=1,a=0;
    16     char ch=getchar();
    17     while (ch < '0'||ch > '9'){
    18         if (ch == '-') x=-1;
    19         ch = getchar();
    20     }
    21     while (ch <= '9'&&ch >= '0')
    22     {
    23         a = a*10 + ch- '0';
    24         ch=getchar();
    25     }
    26     return x*a;
    27 }
    28 struct node
    29 {
    30     int x,y,id;
    31 }a[maxn];
    32 struct edge
    33 {
    34     int next,to,w;
    35 }edge[maxn];
    36 void add(int u,int v,int w)
    37 {
    38     edge[++tot].w=w;
    39     edge[tot].to=v;
    40     edge[tot].next=head[u];
    41     head[u]=tot;
    42 }
    43 bool cmp1(node a,node b)
    44 {
    45     return a.x<b.x;
    46 }
    47 bool cmp2(node a,node b)
    48 {
    49     return a.y<b.y;
    50 }
    51 void Dijkstra(int S)
    52 {
    53     q.push(make_pair(0,S)); memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[S] = 0;
    54     while(!q.empty())
    55     {
    56         int x = q.top().second; 
    57         q.pop(); 
    58         if(vis[x])
    59             continue; 
    60         vis[x] = 1;
    61         for(int i=head[x];i!=0;i=edge[i].next)
    62         {
    63             int to1=edge[i].to;
    64             if(dis[to1] > dis[x] + edge[i].w)
    65             {
    66                 dis[to1] = dis[x] + edge[i].w ;
    67                 q.push(make_pair(-dis[to1],to1));
    68             }
    69         }
    70     }
    71     return;
    72 }
    73 int main()
    74 {
    75     n=read();
    76     for (int i = 1;i <= n;i++)
    77     {
    78         a[i].x=read(),a[i].y=read();
    79         a[i].id=i;
    80     }
    81     sort(a+1,a+n+1,cmp1);
    82     for (int i = 1;i < n;i++)
    83     {
    84         add(a[i].id,a[i+1].id,abs(a[i].x-a[i+1].x));
    85         add(a[i+1].id,a[i].id,abs(a[i].x-a[i+1].x));
    86     }
    87     sort(a+1,a+n+1,cmp2);
    88     for (int i = 1;i < n;i++)
    89     {
    90         add(a[i].id,a[i+1].id,abs(a[i].y-a[i+1].y));
    91         add(a[i+1].id,a[i].id,abs(a[i].y-a[i+1].y));
    92     }
    93     Dijkstra(1);
    94     cout<<dis[n];
    95     return 0;
    96 }
  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12323915.html
Copyright © 2011-2022 走看看