【dijkstra變形】 uva 11367 Full tank?
阿新 • • 發佈:2018-12-12
題目大意: 在一張無向圖中,你的車要從起點走到終點。你走多少距離要耗費多少油。每個地方加油的錢不一樣,你可以不加,加一個單位,加滿。。。。油量箱是有上限的。 一開始你的車油容量為空。 求到終點最便宜花多少錢。
節點:n <= 1000
油容量 c <= 100
詢問次數 q <= 100
思路一:第一眼見到的是拆點,把三元組(u,cost,oil)分別連邊,可惜妥妥TLE
思路二:思考一下dijkstra是如何工作的,有一個d[]陣列存到當前節點最小的距離,用優先佇列保證維護每次取出的節點總是在距離上最優的。
收到以上啟發,我們不妨令mincost[i][j]表示在i節點,容量還有j個單位的油所花費最少的錢。然後用優先佇列維護cost最小的值即可。
#include <bits/stdc++.h> #define CLR(arr) memset(arr,0,sizeof(arr)) #define FOR(i,j) for (int i = 0 ; i < j ; i++) #define FORS(i,j) for (int i = 1 ; i <= j ; ++i) using namespace std; typedef long long ll; int maxCap = 100; struct Edge{ int u,v,dis; }; struct Node{ int u,cost,cap; bool operator < (const Node& rhs) const{ return cost==rhs.cost?cap > rhs.cap: cost>rhs.cost; } }; struct path{ int F[1005][105]; int price[1005]; int ecnt; int n,m; int q; vector<Edge> edge; vector<int> G[1005]; inline void AddEdge(int u,int v,int d) { edge.push_back(Edge{u,v,d}); G[u].push_back(ecnt++); } void read_data() { cin >> n >> m; for (int i = 0 ; i < n ; ++i) scanf("%d",&price[i]); int u,v,d; for (int i = 0 ; i < m ; ++i) { cin >> u >> v >> d; AddEdge(u,v,d); AddEdge(v,u,d); } } void query() { cin >> q; int c,s,e; for (int i = 0 ; i < q ; ++i) { memset(F,0x3f,sizeof(F)); cin >> c >> s >> e; maxCap = c; int ans = getPath(Node{s,0,0},e); if(ans == -1) puts("impossible"); else cout << ans << endl; } } int getPath(Node begin,int end) { F[begin.u][begin.cap] = begin.cost; priority_queue<Node> q; q.push(begin); while(!q.empty()) { Node t = q.top(); q.pop(); int u = t.u; if(u == end) break; int cap = t.cap; int tcost = t.cost; while(cap < maxCap) { cap++; tcost += price[u]; if(F[u][cap] > tcost) { F[u][cap] = tcost; q.push(Node{u,tcost,cap}); } } for (int i = 0; i < G[u].size() ; ++i) { Edge& e = edge[G[u][i]]; int remain = t.cap - e.dis; if(remain >= 0) { int &tmp = F[e.v][remain]; if(tmp > t.cost) { tmp = t.cost; q.push(Node{e.v,t.cost,remain}); } } } } int ans = 0x3f3f3f3f; for (int i = 0 ; i <= maxCap ; ++i) ans = min(ans,F[end][i]); if(ans == 0x3f3f3f3f) return -1; return ans; } }; path solver; int main() { solver.read_data(); solver.query(); return 0; }