Dijkstra+堆优化模板

本文深入探讨了POJ-3268题目的解决方案,利用Dijkstra算法实现两点间最短路径的计算。通过两轮Dijkstra算法分别计算从指定点到所有点以及从所有点到指定点的最短距离,最终找出最大往返距离。代码中详细展示了数据结构的设计,包括节点结构和比较器结构,并实现了优先队列以提高算法效率。

POJ - 3268

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f

using namespace std;
int n,m,x;

struct node{
	vector<pair<int,int> > p;
}path[1005],path2[1005];

struct cmp{
	bool operator()(pair<int,int> a,pair<int,int> b){
		if(a.second>b.second)return true;
		return false;
	}
};

int dis[1005];
int book[1005];
int ans1[1005],ans2[1005];

void dijk(int x){
	for(int i=1;i<=n;i++){
		if(i!=x)dis[i]=inf;
		else dis[i]=0;
	}
	fill(book,book+1005,0);
	
	priority_queue<pair<int,int> ,vector<pair<int,int> >,cmp> que;
	que.push(pair<int,int>(x,0));
	
	for(int i=0;i<path[x].p.size();i++){
		que.push(pair<int,int>(path[x].p[i]));
	}
	
	while(!que.empty()){
		pair<int,int> t=que.top();
		que.pop();
		int u=t.first;
	//	if(dis[u]<t.second)continue;//注释掉速度居然更快 暂时不清楚为什么 可能是数据不存在这种情况但是需要进行<判断 
		
		for(int i=0;i<path[u].p.size();i++){
			if(dis[path[u].p[i].first]>dis[u]+path[u].p[i].second){
				dis[path[u].p[i].first]=dis[u]+path[u].p[i].second;
				que.push(path[u].p[i]);
			}
		}
	}	
}

void dijk2(int x){
	for(int i=1;i<=n;i++){
		if(i!=x)dis[i]=inf;
		else dis[i]=0;
	}
	fill(book,book+1005,0);
	
	priority_queue<pair<int,int> ,vector<pair<int,int> >,cmp> que;
	que.push(pair<int,int>(x,0));
	
	for(int i=0;i<path2[x].p.size();i++){
		que.push(pair<int,int>(path2[x].p[i]));
	}
	
	while(!que.empty()){	
		pair<int,int> t=que.top();
		que.pop();
		int u=t.first;
	//	if(dis[u]<t.second)continue;
		
		for(int i=0;i<path2[u].p.size();i++){
			if(dis[path2[u].p[i].first]>dis[u]+path2[u].p[i].second){
				dis[path2[u].p[i].first]=dis[u]+path2[u].p[i].second;
				que.push(path2[u].p[i]);
			}
		}
	}	
}

int main(){
	while(~scanf("%d%d%d",&n,&m,&x)){
		for(int i=1;i<=m;i++){
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			path[a].p.push_back(pair<int,int>(b,c));
			path2[b].p.push_back(pair<int,int>(a,c));
		}
		
		dijk(x);//x点到其他各点
		for(int i=1;i<=n;i++){
			ans1[i]=dis[i];
		}
	
		dijk2(x);//其他各点到x点
		for(int i=1;i<=n;i++){
			ans2[i]=dis[i];
		}
		
		int max=0;
		for(int i=1;i<=n;i++){
			if(max<(ans1[i]+ans2[i]))max=ans1[i]+ans2[i];
		}
		cout<<max<<endl;
	}

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值