CCF-CSP 交通规划 JAVA 2016-09-04 100分

参考资料:

dijkstra和Floyd算法思想:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html

C++代码版:http://blog.csdn.net/moilk_nepho/article/details/52950546

JAVA优先队列使用:http://www.importnew.com/6932.html

JAVA类中类问题:https://www.baidu.com/s?ie=UTF-8&wd=java%20%E7%B1%BB%E4%B8%AD%E7%B1%BB

Comparable 和Comparator 详解及区别:http://blog.csdn.net/sinat_34979528/article/details/54407678

cannot be cast to java.lang.Comparable解决办法:http://blog.sina.com.cn/s/blog_944bf8ef0101jczp.html

解题思路:

题目要求 “所有城市到首都的最短距离都和原来一样长” 可见这是一个单源最短路径问题。 

且要求出最少要改造多少铁路,即要求:所有符合最短路径条件的边,用这样的边,连通所有点所需要的最小花费。


样例:



package csp2016_09_4;
/**
 * 收获:
 * 到底是对象运算快还是普通运算快 在这里——用静态还是动态好?
 * djs算法和延伸
 * 常见图论算法的写法
 * 类中类的问题
 * final static 
 * List的使用及List[]时要注意每项都实例化
 * 优先队列PriorityQueue
 * Comparator和Comparable区别和使用细节
 * 
 * */
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
  
class Node implements Comparable<Node>{
	//出发点到V点的距离为cost
	public int v=0,cost=0;	
	Node(){}
	Node(int v,int cost){
		this.v = v;
		this.cost = cost;
	}
	public int compare(Node o1, Node o2) {
//		return ((Node)o1).cost-((Node)o2).cost;	//Comparator<默认Object>
		return o1.cost-o2.cost;
	}
	@Override
	public int compareTo(Node o) {
		return this.cost-o.cost;
	}
	
//	public static Comparator<Node> costComparator = new Comparator<Node>(){
//        public int compare(Node c1, Node c2) {
//            return (c1.cost - c2.cost);
//        }
//    };
}

class Edge{
	// 该点到点V的距离为W
	int v,w=0;
	Edge(int v,int w){
		this.v = v;
		this.w = w;
	}
//	int s=0,e=0,w=0;
//	Edge(int s,int e,int w){
//		this.s = s;
//		this.e = e;
//		this.w = w;
//	}
}

public class Main {  
	Main(){
		for (int i = 0; i < G.length; i++) {
			G[i] = new ArrayList();
		}
	}
	final static int MAXN = 10010;
	final static int MAXINT = 0xfffffff;
	
//	ArrayList G[] = new ArrayList[MAXN]; 
	List <Edge>G[] = new ArrayList[MAXN]; 
	boolean vis[] = new boolean[MAXN];	//每个点只应该被访问一次
	int dis[] =new int[MAXN];	//出发点到某点的距离
//	int prev[] = new int[MAXN];	//传统djs,求前驱顶点,得最短路径
	int costo[] = new int[MAXN];	//当满足最短路径条件下,要接通该点所需要的最小花费。
	int n,m;
	
    public static void main(String[] args)  {
    	Main a = new Main();
    	Scanner sc = new Scanner(System.in);
    	a.n = sc.nextInt();
    	a.m = sc.nextInt();
//    	int[][] A = new int[m][3];
//    	for (int i = 0; i < A.length; i++) {
//			for (int j = 0; j < A[i].length; j++) {
//				A[i][j] = sc.nextInt();
//			}
//		}
//    	Main.run();
    	int s,e,w;
    	for (int i = 0; i < a.m; i++) {
    		s = sc.nextInt();
    		e = sc.nextInt();
    		w = sc.nextInt();
//    		Edge edge = a.new Edge(e,w);
    		a.G[s].add(new Edge(e,w));
    		a.G[e].add(new Edge(s,w));	//双向连通
		}
    	a.djs(1);
    	int ans = 0;
    	for (int i = 2; i <= a.n; i++) {	//没有结点0,本题1到1的距离还是0 
    		ans += a.costo[i];
		}
    	System.out.println(ans);
    }
    public void djs(int s){
    	//初始化
    	for (int i = 0; i <= n; i++) {
    		dis[i] = MAXINT;
    		costo[i] = MAXINT;
    		vis[i] = false;
		}
    	//自己到自己肯定是0
    	dis[s] = 0;
    	costo[s] = 0;
    	// 是0不是s 本题不存在结点0		初始开始结点需要是1
    	vis[0] = true;
    	//建立优先队列pq 存储Node结点信息
//    	Node comp = new Node();	//如果调用的是Comparator接口就这样写
//    	Queue<Node> pq = new PriorityQueue<Node>(comp);	
    	Queue<Node> pq = new PriorityQueue<Node>();	
    	//初始化
    	pq.add(new Node(s,0));	

    	Node temp;
    	while(!pq.isEmpty()){
    		temp = pq.poll();	//从最近的开始取  取完删除
    		int v = temp.v;
    		if(!vis[v]){
    			vis[v] = true;
    			//看看你这个点v周围连了几个边
    			int length = G[v].size();
    			//对每个边循环一次
    			for (int i = 0; i < length; i++) {
    				//目标点:vv 
    				int vv = G[v].get(i).v;
    				if(vis[vv]) continue;
    				//从点v到点vv  边长为cost
    				int cost = G[v].get(i).w;
    				//假如从v沿这条边到vv  那么就得到了新的权值
    				int newdis = dis[v] + cost;
    				//eg:A->B=6  A->C=3  C->B=2   已经到C了 发现6>3+2=5
    				if(dis[vv] > newdis){
    					//那起始点A   --->B 的距离就改成5了
    					dis[vv] = newdis;
    					//目前要连通点B且满足最短路径条件  	所需的最小花费就是2了
    					costo[vv] = cost;	//v到VV的花费
    					//下一个,把点B放入pq中
    					pq.add(new Node(vv,dis[vv]));
    				}
    				//eg:A->B=5?	多种距离相同的方案,选取新边最小那个
    				if(dis[vv] == newdis){
    					costo[vv] = Math.min(costo[vv],cost);
    				}
				}
    		}
    	}
    }
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值