JAVA CCF-201712-4 行车路线

欢迎访问我的CCF认证解题目录

 

题目描述

 

 

思路过程

因为有小道大道,所以如果是小道的话就需要先记录当前走了多少的小道距离,如果下一个是大道的话就正常计算,是小道的话就根据刚才记录的距离,用计算。

最短路径问题,看到点只有500个,最开始想用DFS去做的,结果超时了。。边数最大是。。只得了30分,好吧,要不是直接用最短路径有点难搞(其实没想的难),这是你逼我的!看我使出压箱底的公式,接招吧,80分, w(Д)w,有点小尴尬,偷偷瞄一下网上题解,long啊,我考虑到了啊,存储的时候,嗯?等等,计算的时候?w(Д)w,我的权定义的时候是int,来个不就凉了吗。马上改一下,100分了,我...好吧,经过我的总结,以后能定义成long就定义成long,反正第四题空间没超出过   ~()~*

 

 

JAVA代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

class Main {
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//用这个读取数据会快些
		String[] line = br.readLine().split(" ");
		int n = Integer.parseInt(line[0]), m = Integer.parseInt(line[1]), INF = 1000000000;
		ArrayList<ArrayList<Node>> graph = new ArrayList<ArrayList<Node>>();//图
		boolean[] flag = new boolean[n+1];//标志是否访问过
		long[] path = new long[n+1];	//到各点的最小值
		long[] temp = new long[n+1];	//存储已经走过的小道距离
		
		//初始化
		for ( int i = 0; i < n+1; i++ ) {
			graph.add(new ArrayList<Node>());
			path[i] = INF;
		}
		
		//读取数据
		for ( int i = 0; i < m; i++ ) {
			line = br.readLine().split(" ");
			graph.get(Integer.parseInt(line[1])).add(new Node(Integer.parseInt(line[0]), Integer.parseInt(line[2]), Integer.parseInt(line[3])));
			graph.get(Integer.parseInt(line[2])).add(new Node(Integer.parseInt(line[0]), Integer.parseInt(line[1]), Integer.parseInt(line[3])));
		}
		
		path[1] = 0;
		
		while ( true ) {
			int index = -1;
			long min = INF;
			
			for ( int i = 1; i < path.length; i++ ) {	//找出最小值
				if ( !flag[i] && path[i] < min ) {
					index = i;
					min = path[i];
				}
			}
			
			if ( index == -1 || index == n ) break;//已经找到终点的最短路径
			flag[index] = true;
			
			for ( Node node : graph.get(index) ) {
				if ( !flag[node.number] ) {
					if ( node.type == 1 ) {
						//(a+b)2 = a2+2*a*b+b2,应该就是出错在这个if上
						if ( path[index] + 2*temp[index]*node.power + node.power*node.power < path[node.number] ) {
							path[node.number] = path[index] + 2*temp[index]*node.power + node.power*node.power;
							temp[node.number] = node.power + temp[index];	//存储当前进行的小道
						}
					} else {
						if ( path[index] + node.power < path[node.number] ) {
							path[node.number] = path[index] + node.power;
							temp[node.number] = 0;	//小道置为0
						}
					}
				}
			}
		}
		if ( path[n] == INF ) System.out.println("0");//只有一个点时,好像自己想多了
		else System.out.println(path[n]);
	}

}
class Node {
	//类型,编号,权
	int type, number;
	int power;//就是你害我得了80分
	public Node(int type, int number, int power) {
		this.type = type;
		this.number = number;
		this.power = power;
	}
	@Override
	public String toString() {//调试用的
		return "type=" + type + ", number=" + number + ", power=" + power;
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值