1. 程式人生 > >poj 2502 題解 & dijkstra的堆優化

poj 2502 題解 & dijkstra的堆優化

【序言】求單源最短路徑一直是個很熱門的話題。網上,大家也在爭相比試dijkstra和SPFA的優越性。遺憾的是,我一直沒學過dijkstra的堆優化,於是打算好好學習一下。以下是poj上隨便找的一道最短路的題目。

【dijkstra的堆優化】試想,在普通的dij中,每次尋找的當前dis的最小值時,要花費O(N)的效率,這樣實在太不佳了。我們基本的思想是構造一個最小堆,每次找最小值的時候直接取出堆頂即可。詳見這裡。

【STL的基本操作】

1.標頭檔案 #include<queue>

2.定義 priority_queue<x,vector<y>,greater<z

> >q;      -------->>>>>x、y、z是型別名,q是堆的變數名。其中vector是容器,greater可以使自己定義的bool型別(如sort的cmp)。當然,greater是系統已經定義好了的。

3.使用 q.push(x) 往堆中壓入x這個值 

           q.size() 查詢堆中的元素 

           q.pop() 彈出堆頂

           q.top() 返回堆頂元素的值

【注意】我又新定義了一種點對型別,定義方法:typedef pair<x,y>q;x和y是點對型別中每個元素的型別。這樣有什麼好處呢?因為dij的堆中我要存兩個元素:到此點的最小值和這個點的編號。用點對十分方便。

使用方法:make_pair(x,y)。返回點對的型別。

【題目】

Subway
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5708 Accepted: 1846

Description

You have just moved from a quiet Waterloo neighbourhood to a big, noisy city. Instead of getting to ride your bike to school every day, you now get to walk and take the subway. Because you don't want to be late for class, you want to know how long it will take you to get to school. 
You walk at a speed of 10 km/h. The subway travels at 40 km/h. Assume that you are lucky, and whenever you arrive at a subway station, a train is there that you can board immediately. You may get on and off the subway any number of times, and you may switch between different subway lines if you wish. All subway lines go in both directions.

Input

Input consists of the x,y coordinates of your home and your school, followed by specifications of several subway lines. Each subway line consists of the non-negative integer x,y coordinates of each stop on the line, in order. You may assume the subway runs in a straight line between adjacent stops, and the coordinates represent an integral number of metres. Each line has at least two stops. The end of each subway line is followed by the dummy coordinate pair -1,-1. In total there are at most 200 subway stops in the city.

Output

Output is the number of minutes it will take you to get to school, rounded to the nearest minute, taking the fastest route.

Sample Input

0 0 10000 1000
0 200 5000 200 7000 200 -1 -1 
2000 600 5000 600 10000 600 -1 -1

Sample Output

21

Source


【大意】

給出起點、終點的座標。你要從起點走到終點。步行的速度是10km/h。(當然,你在兩個點之間走,肯定是勾股距離最短)。再給出N條地鐵線路,每條給出不小於2個的座標,表示這些座標構成一條線路。在地鐵軌道中,速度是40km/h。我們認為無論何時你到某個站,都恰好有一輛車來。求起點到終點的最小時間。

【程式碼】

#include<stdio.h>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=200+5;
double d[maxn],map[maxn][maxn],ans;
int x[maxn],y[maxn],n,i;
bool flag[maxn];
typedef pair<double,int>Pair;
double dis(int x1,int y1,int x2,int y2)
{
  return sqrt(double((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)))/1000;
}
double dijkstra(int start,int end)
{
  for (int i=1;i<=n;i++) d[i]=2100000000;
  memset(flag,0,sizeof(flag));
  d[start]=0;
  priority_queue< Pair,vector<Pair>,greater<Pair> >q;
  q.push(make_pair(d[start],start));
  while (!q.empty())
  {
    Pair top=q.top();
    q.pop();
    int now=top.second;
    if (flag[now]) continue;
    flag[now]=true;
    for (int j=1;j<=n;j++)
      if ((!flag[j])&&(map[now][j]+d[now]<d[j]))
      {
        d[j]=d[now]+map[now][j];
        q.push(make_pair(d[j],j));
      }
  }
  return d[end];
}
void read()
{
  for (int i=1;i<maxn;i++)
    for (int j=1;j<maxn;j++)
      map[i][j]=2100000000;
  int start=n+1,xx,yy;
  while (scanf("%d%d",&xx,&yy)!=EOF)
  {
    if (xx==-1&&yy==-1)
    {
      for (int i=start;i<n;i++)
      {
        double temp=dis(x[i],y[i],x[i+1],y[i+1])/40;
        if (temp<map[i][i+1]) map[i][i+1]=map[i+1][i]=temp;
      }
      start=n+1;
      continue;
    }
    n++;
    x[n]=xx;y[n]=yy;
  }
  for (int i=1;i<n;i++)
    for (int j=i+1;j<=n;j++)
    {
      double temp=dis(x[i],y[i],x[j],y[j])/10;
      if (temp<map[i][j]) map[i][j]=map[j][i]=temp;
    }
}
  
int main()
{
  scanf("%d%d%d%d",&x[1],&y[1],&x[2],&y[2]);
  n=2;read();
  ans=dijkstra(1,2);ans*=60;
  printf("%.f",ans);
  return 0;
}

相關推薦

poj 2502 題解 & dijkstra優化

【序言】求單源最短路徑一直是個很熱門的話題。網上,大家也在爭相比試dijkstra和SPFA的優越性。遺憾的是,我一直沒學過dijkstra的堆優化,於是打算好好學習一下。以下是poj上隨便找的一道最短路的題目。 【dijkstra的堆優化】試想,在普通的dij中,每次尋

Newcoder Metropolis(多源最短路 + Dijkstra優化題解

題目連結:https://www.nowcoder.com/acm/contest/203/I?tdsourcetag=s_pcqq_aiomsg來源:牛客網 思路:我們用用fa[i]表示距離i最近的大都市,dis[i]表示i距離該大都市的距離。我們先把所有大都市加入初始點,然後跑Dijkstra,如果某一

【Skiing】【POJ - 3037】(dijkstra+優化

題目: Bessie and the rest of Farmer John's cows are taking a trip this winter to go skiing. One day Bessie finds herself at the top left corner of a

hdu 2544 單源最短路問題 dijkstra+優化模板

尋找 問題 col .cn 入隊 ron ava iss cto 最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su

python實現Dijkstra + 優化 + 鏈式前向星

    最近在做網路拓撲相關的研究,各種經典演算法自然是繞不過去的,由於資料量比較大,決定用鏈式前向星來存圖,網上找一圈,PYTHON+鏈式前向星的程式碼沒找到,於是乎決定自己寫一下,不寫不知道,寫了才嚇一跳,程式碼能力真是弱掉渣了。     一、背景介紹

Aizu - ALDS1_12_C:Dijkstra +優化

這個題非常值得一做,儘管我用了很長時間 #include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<queue> #define per

Dijkstra 優化

  就是個小模版qwq,提醒自己一下:   (但這是弱化版的) #include<cstdio> #include<iostream> #include<queue> using namespace std; #define maxn 500005 #define

ALDS1_12_C:Dijkstra +優化

這個題非常值得一做,儘管我用了很長時間 #include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<queue>

dijkstra+優化+鏈式前向星

直接見題:   題目背景 2018 年 7 月 19 日,某位同學在 NOI Day 1 T1 歸程 一題裡非常熟練地使用了一個廣為人知的演算法求最短路。 然後呢? 100 \rightarrow 60100→60; Ag \rightarrow

每日模板一練(Dijkstra優化

大意: 給一個圖,N個點M條邊,求s到t最短路徑 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<s

Invitation Cards【最短路-dijkstra-優化-前向星優化

Invitation Cards In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of t

Dijkstra 優化 鄰接表存圖

#include<bits/stdc++.h> using namespace std; vector<int>vec[105],val[105]; int n,m; int dis[105]; bool vis[105]; int path[105

[Dijkstra+優化]

前言 歡迎來到NOIP考前複習系列。。。。。。今天要講的是Dijkstra。。。 當然,如果有任何錯誤的話,歡迎留言指出喲。。。 演算法作用 Dijkstra演算法用於解決單源最短路問題,即求取從一個給定的起點出發到其他節點的最短距離。 演算法原理 如圖: 我們首先定義一個數組dd,代表我們

Luogu 4779(dijkstra+線段樹優化)(dijkstra+優化

傳送門 題意:模板題,求有向非負權圖的單源最短路 題解: 明說了要卡SPFA,所以只能dijkstra+資料結構優化,不管用堆還是線段樹,只有能到O(nlogn)就OK。 實測線段樹略快。 注意:每次“出隊”時將當前點賦值為INF(如果硬要做刪除操作就只有上平衡樹了

圖論-Dijkstra優化

之前已經寫過樸素的Dijkstra了: int Dijkstra(int x) { int min, k; for(int i=1; i<=n; i++) d[i] =

poj 1511 鄰接表+優化的dijstra

這題最終的意思很簡單,輸入圖,求出從源點到所有點的最短路,再把這個圖的所有邊反向,再求一次源點到所有點的最短路。 這個和poj另一道題很相似,合適這題 的意義在於資料。 你這個圖是無法用鄰接矩陣存下的,因為鄰接矩陣太大了,你只能用鄰接表。 那麼這個題就是用鄰接表的用優先佇列

Dijkstra+優化模板 (手寫簡單易懂)

#include<cstdio> #include<iostream> #define MAXN 2510 #define INF 1000000000 using namesp

最短路~dijkstra優化模板

#include<iostream> #include<cstdio> #include<algorithm> #include<memory.h> #

dijkstra+優化

fine vector pty priority %d bit con cst for http://acm.hdu.edu.cn/showproblem.php?pid=2544 1 #include<bits/stdc++.h> 2 #inclu

優化 dijkstra +路徑

() print inline sizeof light read 堆優化 start csharp #include <iostream> #include <cstdio> #include <algorithm> #inc