题目大意: 在一张无向图中,你的车要从起点走到终点。你走多少距离要耗费多少油。每个地方加油的钱不一样,你可以不加,加一个单位,加满。。。。油量箱是有上限的。 一开始你的车油容量为空。 求到终点最便宜花多少钱。
节点: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;
}