1. 程式人生 > >poj 2387(Dijkstra優先佇列優化)

poj 2387(Dijkstra優先佇列優化)

Description

Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible.

Farmer John’s field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it.

Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.
Input

  • Line 1: Two integers: T and N

  • Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.
    Output

  • Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.
    Sample Input

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
Sample Output

90
Hint

INPUT DETAILS:

There are five landmarks.

OUTPUT DETAILS:

Bessie can get home by following trails 4, 3, 2, and 1.

大致題意:有多組資料,每組資料首先輸入T和n,表示有T條邊和n個點,接下來輸入每兩個點的編號和連線他們的一條邊的長度。問從1到n的最短路程。保證1到n有一條通路。
(注意有多重邊)
思路:Dijkstra求最短路

程式碼如下

程式碼1

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>

using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=1005;
int maps[maxn][maxn];//存兩點間的距離
int dis[maxn];//表示源點到該點的最短路 
int n;//節點數 

struct node
{
    int num;
    int dis;
    friend bool operator <(node a,node b)
    {
        if(a.dis==b.dis) return a.num>b.num;
        return a.dis>b.dis;
    }
};
priority_queue<node> que;//用優先佇列優化

void init()
{
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    maps[i][j]=INF;
}
void Dijkstra(int s)
{
    int vis[maxn];//表示該點是否已經訪問過 
    for(int i=1;i<=n;i++)
    dis[i]=INF;
    memset(vis,0,sizeof(vis));

    dis[s]=0;
    node u;
    u.dis=0;
    u.num=s;
    que.push(u);
    while(!que.empty())
    {
        node u=que.top();
        que.pop();
        int x=u.num;

        if(vis[x])
            continue;
        vis[x]=1;   

        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]>dis[u.num]+maps[u.num][i])
            {
                dis[i]=dis[u.num]+maps[u.num][i];
                node v;
                v.num=i;
                v.dis=dis[i];
                que.push(v);
            }
        }
    }
    printf("%d\n",dis[n]);
 } 

 int main()
 {

    int T,x,y,D;
    while(scanf("%d%d",&T,&n)!=EOF)
    {
        init();
        for(int i=1;i<=T;i++)
        {
            scanf("%d%d%d",&x,&y,&D);
            if(D<maps[x][y])//有多重邊,記錄最短的一條即可
            {
             maps[y][x]=maps[x][y]=D;
            }
         }
         Dijkstra(1);
     }
     return 0;
 }

程式碼2

#include<stdio.h>
#include<string.h>
#include<stdio.h>
#include<cstdio>
#include<iostream>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=1005;
int maps[maxn][maxn];
int vis[maxn];//表示該點是否已經遍歷過 
int dis[maxn];//表示源點到該點的最短路 
int n;//節點數 
void Dijkstra(int s,int e)
{

    memset(dis,INF,sizeof(dis));
    dis[s]=0;
    for(int i=1;i<=n;i++)
    {
        int mini=INF;
        int k=-1;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<mini)
            {
                k=j;
                mini=dis[j];
            }
        }
        vis[k]=1;
        if(k==e)
        {
            printf("%d\n",dis[k]);
            return;
        }
        for(int j=1;j<=n;j++)
        {
            if(!vis[j])
            {
                dis[j]=min(dis[k]+maps[k][j],dis[j]);
            }
        }
    }
 } 

 int main()
 {

    int T,x,y,D;

    while(scanf("%d%d",&T,&n)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        memset(maps,INF,sizeof(maps));
        for(int i=1;i<=T;i++)
        {

            scanf("%d%d%d",&x,&y,&D);
            if(D<maps[x][y])
            {
             maps[x][y]=D;
             maps[y][x]=D;
            }
         }
         Dijkstra(1,n);
     }
     return 0;
 }

相關推薦

poj 2387Dijkstra優先佇列優化

Description Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes

最短路Dijkstra + 優先佇列優化

#include <iostream> #include <cstdio> #include <queue> #include <vector> using namespace std; const int Ni = 20001

Buy a Ticket 最短路設虛擬節點+Dijkstra優先佇列優化

Musicians of a popular band "Flayer" have announced that they are going to "make their exit" with a world tour. Of course, they will visit Berland as

Huffman樹使用優先佇列優化

實現了使用佇列進行優化的Huffman樹。 #include <iostream> #include <stdlib.h> #include <queue> #include <vector> using namespace

Dijkstra演算法鄰接表+優先佇列優化 建立虛點】HDU

Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated his  fences they were separated into differen

Dijkstra演算法鄰接表+優先佇列優化

Dijkstra演算法是在圖論中應用很廣的一種演算法,它本質上是貪心的成功應用。它可以求加權圖的單源最短路。但是如果不優化的話,它的複雜度是O(n方),比較低效,一般我們採用鄰接表+優先佇列的優化。#include<bits/stdc++.h> using nam

CCF-CSP201609-4 交通規劃Dijkstra+優先佇列

題目連結 問題描述 試題編號: 201609-4 試題名稱: 交通規劃 時間限制: 1.0s 記憶體限制: 256.0MB 問題描述: 問題描述   G國國王來中國參觀後,被中國的高速鐵路深深的震撼,決定為自己

迪傑斯特拉優先佇列優化

使用鄰接矩陣實現的dijkstra演算法的複雜度是O(V²)。使用鄰接表的話,更新最短距離只需要訪問每條邊一次即可,因此這部分的複雜度是O(E).但是每次要列舉所有的頂點來查詢下一個使用的頂點,因此最終複雜度還是O(V²)。在|E|比較小時,大部分的時間都花在了

codeforces D. Edge Deletion+最短路樹優先佇列優化

題目連結:http://codeforces.com/contest/1076/problem/D 題目大意: 在一個n個點m條邊的無向圖中起點為1,設初始到達第i個點的最短距離為d[i], 現在要求在圖上刪邊,使剩下的邊等於k條,並讓儘量多的點d[i]與之前相

POJ 3253貪心 + 優先佇列

《挑戰程式設計競賽》,初級篇–樹 // 貪心 + 優先佇列(大根堆,小根堆) #include <iostream> #include <cstdio> #include <queue> using namespace

P3084 [USACO13OPEN]照片Photo dp+單調佇列優化

題目連結:傳送門 題目: 題目描述 Farmer John has decided to assemble a panoramic photo of a lineup of his N cows (1 <= N <= 200,000), which, as always

HDU 3401 TradeDP + 單調佇列優化

任重而道遠 Recently, lxhgww is addicted to stock, he finds some regular patterns after a few days' study. He forecasts the next T days' stock market. On

HDU 3401 Tradedp+單調佇列優化

Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5843  &

Codeforces 1077F2 Pictures with Kittens (hard version)DP+單調佇列優化

題目連結:Pictures with Kittens (hard version) 題意:給定n長度的數字序列ai,求從中選出x個滿足任意k長度區間都至少有一個被選到的最大和。 題解:資料量5000,O(n^3)的DP不適用。需要加個單調佇列優化。 注意每次是從$[i-k,i)$區間,選擇加上ai。每次

HDU 6438 Buy and Resell貪心+優先佇列+set

Description 有nnn個城市,第iii個城市商品價格為aia_iai​,從111城市出發依次經過這nnn個城市到達nnn城市,在每個城市可以把手頭商品出售也可以至多買一個商品,問最大收益以及在

PriorityQueue+Dijkstra優先佇列優化Dijkstra

前面分別介紹了“原生的Dijkstra”即毫無優化的Dijkstra,但這種Dijkstra的效率較低為n^n,因此面對較大資料量的時候需要對其進行優化,也就是優化所採用的貪心策略的實現,因此就有了Heao+Dijkstra堆優化的Dijkstra,但是堆優化的實現很複雜,

Poj 3255Dijkstra求次短路

Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old home too quickly, be

HDU-3401:Tradedp+單調佇列優化

題目大意: 就是有一個人知道每一天的股票的購入和賣出的價錢(注意只有一種股票),並且每天能夠購入和賣出的股票的數量也是有限制的。第 i 天買的股票也只能第 i+w+1 天賣出。但是無論何時,他手中持有的股票的數量不能超過m、問他本金無限的情況下最多盈利多少。 題意解

Magical Girl Haze (分層圖 + 最短路徑優先佇列優化

There are NNN cities in the country, and MMM directional roads from uuu to v(1≤u,v≤n)v(1\le u, v\le n)v(1≤u,v≤n). Every road has a distanc

Luogu 4779dijkstra+線段樹優化dijkstra+堆優化

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