問題描述
小明和小芳出去鄉村玩,小明負責開車,小芳來導航。
小芳將可能的道路分為大道和小道。大道比較好走,每走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。
現在小芳拿到了地圖,請幫助她規划一個開車的路線,使得按這個路線開車小明的疲勞度最小。
小芳將可能的道路分為大道和小道。大道比較好走,每走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號路口是連通的。
接下來 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
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
樣例說明
從1走小道到2,再走小道到3,疲勞度為5
2=25;然后從3走大道經過4到達5,疲勞度為20+30=50;最后從5走小道到6,疲勞度為1。總共為76。
80分.. 賽后還沒想怎么優化.. 以后再解決吧
#include<bits/stdc++.h> using namespace std; const long long INF = 1e18; int n,m; struct node{ int to; long long cost; }; struct edge{ int id; long long cost; int len; bool operator < (const edge & a)const { return cost > a.cost; } }; vector<node> G[510][2]; long long d[510]; priority_queue<edge>que; long long p2(long long a){ return a * a; } int solve(){ fill(d,d+n+1,INF); d[1] = 0; que.push({1,0,0}); while(!que.empty() ){ edge a = que.top(); que.pop(); int v = a.id; if(v == n) break; if(d[v] < a.cost) continue; for(int i=0;i<G[v][0].size();i++){ node e = G[v][0][i]; if(d[e.to] > d[v] + e.cost){ d[e.to] = d[v] + e.cost; que.push(edge{e.to,d[e.to],0}); } } for(int i=0;i<G[v][1].size();i++){ node e = G[v][1][i]; int cost = p2(a.len+e.cost)-p2(a.len); if(d[e.to] > d[v] + cost){ d[e.to] = d[v] + cost; que.push(edge{e.to,d[e.to],a.len+e.cost}); } } } return d[n]; } int main () { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ int t,a,b; long long c; scanf("%d %d %d %lld",&t,&a,&b,&c); G[a][t].push_back({b,c}); G[b][t].push_back({a,c}); } cout << solve() <<endl; return 0; }