CCF 201712 4 行車路線 (spfa)

2021-08-17 00:27:02 字數 1638 閱讀 7199

小明和小芳出去鄉村玩,小明負責開車,小芳來導航。

小芳將可能的道路分為大道和小道。大道比較好走,每走 1 公里小明會增加 1 的疲勞度。小道不好走,如果連續走小道,小明的疲勞值會快速增加,連續走 s 公里小明會增加 s^2 的疲勞度。

例如:有 5 個路口,1 號路口到 2 號路口為小道,2 號路口到 3 號路口為小道,3 號路口到 4 號路口為大道,4 號路口到 5 號路口為小道,相鄰路口之間的距離都是 2 公里。如果小明從 1 號路口到 5 號路口,則總疲勞值為 (2+2)^2+2+2^2=16+2+4=22 。

現在小芳拿到了地圖,請幫助她規劃乙個開車的路線,使得按這個路線開車小明的疲勞度最小。

輸入的第一行包含兩個整數 n, m,分別表示路口的數量和道路的數量。路口由 1 至 n 編號,小明需要開車從 1 號路口到 n 號路口。

接下來 m 行描述道路,每行包含四個整數 t, a, b, c,表示一條型別為 t,連線 a 與 b 兩個路口,長度為 c 公里的雙向道路。其中 t 為 0 表示大道,t 為 1 表示小道。保證 1 號路口和 n 號路口是連通的。

輸出乙個整數,表示最優路線下小明的疲勞度。

6 7

1 1 2 3

1 2 3 2

0 1 3 30

0 3 4 20

0 4 5 30

1 3 5 6

1 5 6 1

76
對於同乙個點,假設最後一次從大道走過來和從小道走過來的花費是一樣的,顯然大道比較划算,因為它對下一次走小道的消耗沒有貢獻,從而可以保證最優解。

那麼,我們把大道和小道分開計算。

首先通過 floyd 演算法合併一下所有的小道,然後再通過 spfa 尋找最優解。

每一次的迭代中我們只需要考慮當前狀態的轉移即可:[大道/小道 -> 大道]、[大道 -> 小道]

#include

#define io ios::sync_with_stdio(false);\

cin.tie(0);\

cout.tie(0);

#define inf 0x3f3f3f

using

namespace

std;

typedef

long

long ll;

const

int maxn = 5e2+10;

int n,m;

ll g[maxn][maxn];

ll g2[maxn][maxn];

ll dist[maxn];

ll dist2[maxn];

bool vis[maxn];

void floyd()

void init()

void spfa(int st,int ed)

if(g2[u][i]!=4557430888798830399ll)

}if(flag && !vis[i])}}

}int main()

floyd();

spfa(1,n);

cout

0;}

CCF 201712 4 行車路線

思路 用兩個陣列維護到達某個點的最小大路距離和最小小路距離,注意結果中間過程可能爆int,不加long long 只有70分。有一種特殊情況就是通過走兩次大路,消除連續的小路值,這裡就是用兩個陣列維護的原因。include using namespace std const int maxn 100...

CCF201712 4 行車路線

一 題目大意 問題描述 小明和小芳出去鄉村玩,小明負責開車,小芳來導航。小芳將可能的道路分為大道和小道。大道比較好走,每走1公里小明會增加1的疲勞度。小道不好走,如果連續走小道,小明的疲勞值會快速增加,連續走 s公里小明會增加 s2的疲勞度。例如 有5個路口,1號路口到2號路口為小道,2號路口到3號...

ccf 2017 12 4行車路線

dijkstra變形,注意點 1.雖然題目說最終答案不會超過 10 6,但是中間過程可能超int啊 超了以後溢位變小,可能會影響到最後的解 所以還是乖乖用long long 儲存吧 2.圖的話 一定要考慮重邊和反向邊 還是只有70分 看到網上直接用sum i 記錄以當前小路為結尾的前面的連續小路之和...