POJ - 3268 单源最短路

时间:2022-11-16 07:56:37

题意:给定一些有向边,以及一个目的地,从某个点到达目的地,再从目的地回到那个点。共有n个点,问这n个点花费最大是多少?

思路:从目的地回去直接把目的地作为源点即可。那么从某个点到达目的地应该如何得到最小花费?假设1-2-3,3作为目的地,可以看做3-2-1,即把所有边逆转,以目的地作为源点,即可求得所有点到目的地的最短距离。

AC代码

#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 1000 + 5;
int d1[maxn], d2[maxn], vis[maxn];
int n, m, goal;
vector<int>G[maxn];

struct Edge{
	int from, to, dist;
	Edge() {}
	Edge(int u, int v, int d):from(u), to(v), dist(d){}
};
vector<Edge>edges, rever;
void add_eage(int u, int v, int cost) {
	edges.push_back(Edge(u, v, cost));
	int m = edges.size();
	G[u].push_back(m-1);
}

struct node{
	int d, u;
	node(){}
	node(int d, int u):d(d), u(u){}
	bool operator < (const node &p) const {
		return d > p.d;
	}
};

void dijkstra(int s, int d[]) {
	priority_queue<node>q;
	d[s] = 0;
	memset(vis, 0, sizeof(vis));
	q.push(node(0, s));
	while(!q.empty()) {
		node p = q.top(); q.pop();
		int u = p.u;
		if(vis[u]) continue;
		vis[u] = 1;
		for(int i = 0; i < G[u].size(); ++i) {
			Edge &e = edges[G[u][i]];
			if(d[u] + e.dist < d[e.to]) {
				d[e.to] = d[u] + e.dist;
				q.push(node(d[e.to], e.to));
			}
		}
	}
}

void init() {
	for(int i = 1; i <= n; ++i) G[i].clear();
	edges.clear();
}

int main() {
	while(scanf("%d%d%d", &n, &m, &goal) == 3) {
		init();
	    int u, v, cost;
	    rever.clear();
	    for(int i = 0; i < m; ++i) {
	 		scanf("%d%d%d", &u, &v, &cost);
	 		rever.push_back(Edge(v, u, cost));
	 	   	add_eage(u, v, cost);
	    }
	    memset(d1, inf, sizeof(d1));
	    dijkstra(goal, d1);
	    init();
	    for(int i = 0; i < rever.size(); ++i) {
	    	int u = rever[i].from, v = rever[i].to, cost = rever[i].dist;
	    	add_eage(u, v, cost);
		}
		memset(d2, inf, sizeof(d2));
		dijkstra(goal, d2);
		int ans = 0;
		for(int i = 1; i <= n; ++i) {
			ans = max(d1[i]+d2[i], ans);
		}
		printf("%d\n", ans);
	}
	return 0;
} 

如有不当之处欢迎指出!