0
点赞
收藏
分享

微信扫一扫

Bridges and Tunnels

爱写作的小土豆 2022-01-15 阅读 25
图论算法

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;
}
举报

相关推荐

0 条评论