51nod 1459迷宫游戏 Dijkstra堆优化
题意:给定源点和终点, 每经过一个点就会得到该点对应的分数, 每走过一条边,就会增加相应的时间,让你求源点到终点的最短时间以及在该最短时间下的最终最大得分。
分析: 依旧还是带权单源点最短路。还是用d[i].first表示从源点到i点的路径长度,用d[i].second表示从源点到i点的得分情况。
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
typedef __int64 LL;
//typedef long long LL;
typedef unsigned int uint;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int MAXN = 500 + 5;
const int MAXM = 600 + 5;
int N, M, src, dest;
int x, y, z;
int A[MAXN];
struct Edge {
int u, v, cost;
Edge() {}
Edge(int u, int v, int c) : u(u), v(v), cost(c) {}
};
struct QNode {
int u, cost, sco;
bool operator < (const QNode& e) const {
if (cost == e.cost) {
return sco > e.sco;
}
return cost < e.cost;
}
bool operator > (const QNode& e) const {
return !(*this < e);
}
} cur, rear;
vector<Edge> edges;
vector<int> G[MAXN];
PII d[MAXN];
bool vis[MAXN];
priority_queue<QNode, vector<QNode>, greater<QNode> > Q;
void init() {
edges.clear();
for (int i = 0; i < N; i ++) {
G[i].clear();
d[i].fst = INF;
d[i].snd = 0;
}
}
void addEdge(int u, int v, int dist) {
Edge e(u, v, dist);
edges.push_back(e);
int m = edges.size();
G[u].push_back(m - 1);
}
void dijkstra() {
memset(vis, false, sizeof(vis));
while(!Q.empty()) Q.pop();
cur.u = src;
cur.cost = 0;
cur.sco = A[cur.u];
d[cur.u].fst = 0;
d[cur.u].snd = A[cur.u];
Q.push(cur);
while(!Q.empty()) {
cur = Q.top();
Q.pop();
int u = cur.u;
if(vis[u]) continue;
vis[u] = true;
for(uint i = 0; i < G[u].size(); i ++) {
Edge& e = edges[G[u][i]];
int &v = e.v;
if(vis[v]) continue;
if(d[v].fst > d[u].fst + e.cost || (d[v].fst == d[u].fst + e.cost && d[v].snd < d[u].snd + A[v])) {
d[v].fst = d[u].fst + e.cost;
d[v].snd = d[u].snd + A[v];
rear.u = v;
rear.cost = d[v].fst;
rear.sco = d[v].snd;
Q.push(rear);
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
// FIN;
#endif // ONLINE_JUDGE
while (~scanf("%d %d %d %d", &N, &M, &src, &dest)) {
init();
for (int i = 0; i < N; i ++) {
scanf("%d", &A[i]);
}
for (int i = 0; i < M; i ++) {
scanf("%d %d %d", &x, &y, &z);
addEdge(x, y, z);
addEdge(y, x, z);
}
dijkstra();
printf("%d %d\n", d[dest].fst, d[dest].snd);
}
return 0;
}