POJ 3268

下意识想到了Floyd算法,不过在寻找数据的时候才发现没有仔细分析时间复杂度的弊端(也可能是因为自己这方面的能力弱,所以抵触去分析时间复杂度)
利用刘汝佳的模板,dijkstra是可以满足时间复杂度要求的解法。此外,单源最短路径和单“汇”最短路径其实是对称的问题(正是本题需要dijkstra同时求解的两个问题),对于数据特殊处理即可解决,所以采取的思路是牺牲空间,开对偶的数组来实现这两个问题的同时求解。

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

const int maxn= 1005;

struct Edge
{
	int f, t, d;	
};
struct HeapNode
{
	int u, d;
	bool operator < (const HeapNode &rhs) const
	{
		return this->d > rhs.d;
	}	
};
int n, m, x;
vector<int> G[2][maxn];
vector<Edge> edges[2];
int dis[2][maxn], vis[2][maxn];

void BiAddEdge(int &a, int &b, int &t)
{
	edges[0].push_back((Edge){a, b, t});
	G[0][a].push_back(edges[0].size()-1);
	edges[1].push_back((Edge){b, a, t});
	G[1][b].push_back(edges[1].size()-1);
}
void Dijkstra(int s, int id)
{
	priority_queue<HeapNode> Q;
	memset(dis[id], 0x3f, sizeof(dis[id]));
	memset(vis[id], 0, sizeof(vis[id]));
	dis[id][s]= 0;
	Q.push((HeapNode){s, 0});

	while (!Q.empty()){
		HeapNode p= Q.top();
		Q.pop();
		int u= p.u;
		if (vis[id][u]){
			continue;
		}
		vis[id][u]= 1;
		
		for (vector<int>::iterator gIter= G[id][u].begin(); 
			G[id][u].end()!= gIter; ++gIter){
			Edge &e= edges[id][*gIter];
			if (e.d+dis[id][u]< dis[id][e.t]){
				dis[id][e.t]= e.d+dis[id][u];
				Q.push((HeapNode){e.t, dis[id][e.t]});
			}
		}
	}
}
void Init()
{
	for (int i= 1; i<= n; ++i){
		G[0][i].clear();
		G[1][i].clear();
	}
	edges[0].clear();
	edges[1].clear();
}

int main(int argc, char const *argv[])
{
	scanf("%d %d %d", &n, &m, &x);
	int a, b, t;
	int ans = 0;
	Init();
	for (int i= 0; i< m; ++i){
		scanf("%d %d %d", &a, &b, &t);
		BiAddEdge(a, b, t);
	}
	Dijkstra(x, 0);
	Dijkstra(x, 1);

	for (int j= 1; j<= n; ++j){
		ans= max(ans, dis[0][j]+dis[1][j]);
	}
	printf("%d\n", ans);
	return 0;
}
posted @ 2021-04-05 15:04  IdiotNe  阅读(38)  评论(0编辑  收藏  举报