感官难度: C = D < A < E < B C=D<A<E<B C=D<A<E<B。
A Bridges and Tunnels
题意:给定一张无向图,图上边分为室外和室内两类,每条边有权值。求以室外的边权和为第一关键字,室内和室外的边权和为第二关键字的最短路。
直接用 pair 存一下这两个关键字即可。
#include <bits/stdc++.h>
#define INF 10000000000000000ll
using namespace std;
typedef long long ll;
typedef pair<int, pair<ll, ll> > pill;
int n, m, p;
int to[80005], nxt[80005], tp[80005];
int w[80005], at[4005] = {
0}, cnt = 0;
pair<ll, ll> dis[4005];
priority_queue<pill, vector<pill >, greater<pill > > pq;
int main(){
scanf("%d%d%d", &n, &m, &p);
char opt[3];
for (int i = 0, u, v, ww; i < m; ++i){
scanf("%d%d%d%s", &u, &v, &ww, opt);
int tpp = (opt[0] == 'I' ? 0: 1);
to[++cnt] = v, nxt[cnt] = at[u], w[cnt] = ww, tp[cnt] = tpp,
at[u] = cnt;
to[++cnt] = u, nxt[cnt] = at[v], w[cnt] = ww, tp[cnt] = tpp,
at[v] = cnt;
}
while (p--){
int u, v;
scanf("%d%d", &u, &v);
for (int i = 0; i < n; ++i)
dis[i].first = dis[i].second = INF;
dis[u].first = dis[u].second = 0;
pq.push(make_pair(u, dis[u]));
for (; ; ){
while (!pq.empty()){
if (pq.top().second > dis[pq.top().first])
pq.pop();
else break;
}
if (pq.empty()) break;
pill tmp = pq.top();
pq.pop();
int h = tmp.first;
ll dis_o = tmp.second.first, dis_tot = tmp.second.second;
for (int i = at[h]; i; i = nxt[i]){
if (tp[i]){
pair<ll, ll> tmp_dis(dis_o + w[i], dis_tot + w[i])