Bridges and Tunnels
我们常规的单源最短路是给你两个点(u,v),让你求出u到v的最短路;
这个题只是在常规最短路的基础上附加了一个条件(在外出时间最少的条件下找到两点之间的最短路),如果这里所有的边都在室外或都在室内,那么这个题就和常规最短路没有区别。
我的这里的处理方式如下:
我们增加一个数组out,表示当前点离起点的最短室外距离,u表示当前点;
1、当前边是室内的边:
①out[v] > out[u]
: 松弛out和dis,并将新的v,out[v],dis[v]加入队列;
②out[v] == out[u] && dis[v] > dis[u] + e[u][i].w
: 松弛dis,并将新的v,out[v],dis[v]加入队列;
2、当前边是室外边:
①out[v] > out[u] + e[u][i].w
:松弛out和dis,并将新的v,out[v],dis[v]加入队列;
②out[v] == out[u] + e[u][i].w && dis[v] > dis[u] + e[u][i].w
: 松弛dis,并将新的v,out[v],dis[v]加入队列;
Code:
#include<bits/stdc++.h>
#define bug(x) cout<< #x <<" = "<< x <<endl;
using namespace std;
typedef long long ll;
typedef pair<int,int> PI;
const int N = 4e4 + 10;
const int mod = 2147483648;
const ll INF=0x3f3f3f3f3f3f3f3f3f3f3f3f;
int n,m,p;
struct Node {
int now;
ll outdis,sumdis;
friend bool operator<(Node x,Node y) {
if(x.outdis == y.outdis) return x.sumdis > y.sumdis;
return x.outdis > y.outdis;
}
};
struct edge {
int to;
ll w;
char op;
};
ll out[N],dis[N];
vector<edge> e[N];
void dijkstra(int st) {
memset(out,INF,sizeof(out));
memset(dis,INF,sizeof(dis));
priority_queue<Node> q;
out[st] = dis[st] = 0;
q.push({st,0,0});
while(q.size()) {
Node tep = q.top();
q.pop();
int u = tep.now;
for(int i=0; i<e[u].size(); i++) {
int v = e[u][i].to;
if(e[u][i].op == 'I') {
if(out[v] > out[u]) {
out[v] = out[u];
dis[v] = dis[u] + e[u][i].w;
q.push({v,out[v],dis[v]});
}
else if(out[v] == out[u] && dis[v] > dis[u] + e[u][i].w) {
dis[v] = dis[u] + e[u][i].w;
q.push({v,out[v],dis[v]});
}
} else {
if(out[v] > out[u] + e[u][i].w) {
out[v] = out[u] + e[u][i].w;
dis[v] = dis[u] + e[u][i].w;
q.push({v,out[v],dis[v]});
} else if(out[v] == out[u] + e[u][i].w && dis[v] > dis[u] + e[u][i].w) {
dis[v] = dis[u] + e[u][i].w;
q.push({v,out[v],dis[v]});
}
}
}
}
}
int main() {
cin >> n >> m >> p;
int u,v,w;
char c;
for(int i=1; i<=m; i++) {
cin >> u >> v >> w >> c;
e[u].push_back({v,w,c});
e[v].push_back({u,w,c});
}
while(p--) {
cin >> u >> v;
dijkstra(u);
if(dis[v] == INF) puts("IMPOSSIBLE");
else printf("%lld %lld\n",out[v],dis[v]);
}
return 0;
}