SW练习_POJ3268_双向多次迪杰斯特拉

本文详细解析了如何使用最短路径算法计算两点间往返的最短距离,通过具体实例介绍了算法的实现过程,包括初始化参数、创建邻接列表、利用优先队列进行松弛操作等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先计算从X到其它点的最短路径,作为回去的路

再分别计算下每个点到X的路径,作为去的路

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.PriorityQueue;

public class Main{
    public static int N;
    public static int[] len ; // 保存start到其他各点的最短路径
    public static LinkedList<Edge3268>[] list;

    public static int[] lenB;
    public static int _MAX_V=10000009;

    public static void main(String[] args) throws Exception{
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        String[] str=reader.readLine().split(" ");
        N=Integer.parseInt(str[0]);//农场的数量
        int M=Integer.parseInt(str[1]);//路的数量
        int X=Integer.parseInt(str[2]);//party举行的地点

        list=new LinkedList[N+1];
        len=new int[N+1];
        lenB=new int[N+1];
        for (int i = 0; i <list.length ; i++) {
            list[i]=new LinkedList<Edge3268>();
        }
        for (int i = 0; i < M; i++) {
            str=reader.readLine().split(" ");
            int from=Integer.parseInt(str[0]);
            int to=Integer.parseInt(str[1]);
            int dis=Integer.parseInt(str[2]);
            list[from].add(new Edge3268(from,to,dis));
        }

        int max=0;
        process(X);//此处计算的是从 终点X 到其它点的距离 ,用来计算返回的路程  从X开始到其他点i的最短记录,结果保存在len[i]里

        for (int i = 1; i <=N ; i++) { //此处计算的是 从i开始,到其他点的最短距离,其中包含了i->X的最短距离,保存在 lenB[X]里
            processB(i);
            //System.out.printf("len[%d]:%d  lenB[%d]:%d  \n",i,len[i],X,lenB[X]);
            if(len[i] + lenB[X] >max){
                max=len[i]+lenB[X];
            }
        }
        System.out.println(max);

        reader.close();
    }

    public static void process(int start){//可以计算从start开始,到其他点的最短记录
        PriorityQueue<Edge3268> pq=new PriorityQueue<Edge3268>();
        pq.add(new Edge3268(start,start,0));
        Arrays.fill(len,_MAX_V);
        len[start]=0;

        while( !pq.isEmpty()){
            Edge3268 e=pq.poll();
            for (Edge3268 temp :list[e.to]) {//将这个点的其他边都加入进来
                if(len[temp.to] > len[temp.from] +temp.dis){//松弛一下
                    len[temp.to] = len[temp.from] +temp.dis;
                    pq.add(temp);
                }
            }
        }
    }

    public static void processB(int start){//可以计算从start开始,到其他点的最短记录
        PriorityQueue<Edge3268> pq=new PriorityQueue<Edge3268>();
        pq.add(new Edge3268(start,start,0));
        Arrays.fill(lenB,_MAX_V);
        lenB[start]=0;
        while( !pq.isEmpty()){
            Edge3268 e=pq.poll();
            for (Edge3268 temp :list[e.to]) {//将这个点的其他边都加入进来
                if(lenB[temp.to] > lenB[temp.from] +temp.dis){//松弛一下
                    lenB[temp.to] = lenB[temp.from] +temp.dis;
                    pq.add(temp);
                }
            }
        }
    }


}
class Edge3268 implements Comparable<Edge3268>{
    public Edge3268(int from, int to, int dis) {
        this.from = from;
        this.to = to;
        this.dis = dis;
    }

    int from;
    int to;
    int dis;


    @Override
    public int compareTo(Edge3268 o) {
        return this.dis-o.dis;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值