欢迎访问我的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;
}
}