1. 程式人生 > >[四連測(二)]路徑規劃(path)

[四連測(二)]路徑規劃(path)

題目描述

有n個點,m條無向邊,有A,B兩個人,初始時刻A在點1,B在點2,他們要走到點n去。A每走一條邊,要消耗B單位能量,B每走一條邊,要消耗E單位能量。如果A,B相伴走,則只消耗P單位的能量。請問A,B走到點n,最少要消耗多少能量?

輸入資料保證1和n,2和n連通。

輸入

第一行包含整數B,E,P,N和M,所有的整數都不超過40000,N>=3.

接下來M行,每行兩個整數,表示該無向邊連線的兩個頂點。

輸出

一個整數,表示最小要消耗的能量。

樣例輸入

4 4 5 8 8
1 4
2 3
3 4
4 7
2 5
5 6
6 8
7 8

樣例輸出

22

解題思路

看起來還挺複雜的,令人想打暴搜,不過,此題倒真是跟搜尋有關,需要利用圖的遍歷。我們要求的路程其實就可以看成是兩人走到一個點,然後再一起走到n點所用的最小花費,由於每走一步花費固定,我們就可以用3個dis陣列來儲存三個點(1,2,n)到i點的最小步數,這樣處理,我們不用通過什麼SPFA那些的圖論演算法,用深搜就可以解決了。最後再列舉1到n,求出這三個路程的最小值即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<cstdlib>
#define N 40005
using namespace std;
/*struct edge(){
    int u,v;
    edge(){};
    edge(int U,int V){
        u = U;
        v = V;
    }
};*/
int b,e,p,n,m , dis1[N], dis2[N],dis3[N],vis[N] , ans = N*N;
int que[N],head,tail;
vector<int>G[N];
void bfs(int step,int dis[]){
    memset(vis,0,sizeof(vis));
    dis[step] = 0;
    vis[step] = 1;
    head = tail = 1;
    que[head] = step;
    while (head <= tail){
        int t = que[head];
        int len = G[t].size();
        for (int i = 0; i < len ; i ++ ){
            if (!vis[G[t][i]]){
                que[++ tail] = G[t][i];
                vis[G[t][i]] = 1;
                dis[G[t][i]] = dis[t] + 1;
            }
        }
        head ++ ;
    }
}
int main(){
    scanf("%d%d%d%d%d",&b,&e,&p,&n,&m);
    for (int i = 1;i <= m ;i ++ ){
        int a,b;
        scanf("%d%d",&a,&b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    bfs(1,dis1);
    bfs(2,dis2);
    bfs(n,dis3);
    for (int i = 1 ;i <= n;i ++ ){
        ans = min(ans , dis1[i] * b + dis2[i] * e + dis3[i] * p);
    }
    printf("%d",ans);
}

總結

這樣看起來這道題挺水啊,事實上是這樣的,基本沒考到什麼高階演算法,關鍵看你是否找到了題目中這樣的性質或者說是這樣做的思路。事實證明一些圖論題目可以說並沒有這麼難吧。考試的時候可以說是沒怎麼看這道題,看了一下,發現是有關圖論的,當場就有點怕,又一直在想這是怎樣的演算法才可以通過,都沒有仔細算過。當時還想了一些特殊的點,但對於正確演算法都沒有太大的實際意義。於是,我發現題目當中的一些特殊性質還是要能夠抓住,這樣才能令做題如有神助。(實話說,第一道題耗費了我大量時間,導致全盤爆炸,可以說是模擬考試中考得最差的一次,不過事實證明,這道題如果我打了樣例,我將上升近10名。。。。)