HDUOJ_2066(一个人的旅行)(dijkstra)

HDUOJ_2066(一个人的旅行)(dijkstra)

一个人的旅行

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24736    Accepted Submission(s): 8573

Problem Description
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
Input
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。
Output
输出草儿能去某个喜欢的城市的最短时间。
Sample Input
  
  
6 2 3 1 3 5 1 4 7 2 8 12 3 8 4 4 9 12 9 10 2 1 2 8 9 10
Sample Output
  
  
9
My  solution:
/*2015.8.18*/ 
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF   0x3f3f3f3f
using namespace std;
int map[1100][1100],d[1100],mark[1100],n,m1[1100],w1[1100];
void dijkstra(int s)
{
	int i,v;
	d[s]=0;/*起点距离起点的距离为0*/
	while(1)
	{
		v=-1;
		for(i=0;i<1010;i++)/*由于题目没说明城市有多少个,因此这里的i值设为上限*/
		if(!mark[i]&&(v==-1||d[v]>d[i]))
	    v=i;
	    if(v==-1)
	    break;
	    mark[v]=1;
	    for(i=0;i<1010;i++)
	    d[i]=min(d[i],d[v]+map[v][i]);
	}
}
int main()
{
	int m,w,i,a,b,c,t,j;
	while(scanf("%d%d%d",&n,&m,&w)==3)
	{
		t=INF;
		memset(map,0x3f,sizeof(map));
		for(i=0;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(map[a][b]>c)/*可能会有重边,选取时间最短的数据*/
			{
				map[a][b]=c;
				map[b][a]=c;
			}	
		}
		for(i=0;i<m;i++)
		scanf("%d",&m1[i]);/*与村镇相连的城市,可以当作起点,起点有多个*/
		for(i=0;i<w;i++)
		scanf("%d",&w1[i]);/*终点有多个*/
		for(i=0;i<m;i++)/*调用dijkstra函数,通过for循环设置不同起点*/
		{
			memset(mark,0,sizeof(mark));/*每调用dijkstra函数一次,标记数组(mark)和记录数组(d)都要重新初始化*/
			memset(d,0x3f,sizeof(d));/*map数组不能初始化,因为map数组记录的是两个城市之间的车程*/
			dijkstra(m1[i]);
			for(j=0;j<w;j++)/*通过for循环设置不同终点*/
		  {
			   if(d[w1[j]]<t)/*在所有可选择的情况中,找到花费最小的时间*/
			   t=d[w1[j]];
		  }
		}
		printf("%d\n",t);	
	}	
	return 0;


 

以下是Java实现Dijkstra算法的代码,该算法用于在加权图中找到最短路径: ```java import java.util.*; public class DijkstraAlgorithm { private static final Graph.Edge[] GRAPH = { new Graph.Edge("A", "B", 7), new Graph.Edge("A", "D", 5), new Graph.Edge("B", "C", 8), new Graph.Edge("B", "D", 9), new Graph.Edge("B", "E", 7), new Graph.Edge("C", "E", 5), new Graph.Edge("D", "E", 15), new Graph.Edge("D", "F", 6), new Graph.Edge("E", "F", 8), new Graph.Edge("E", "G", 9), new Graph.Edge("F", "G", 11) }; private static final String START = "A"; private static final String END = "G"; public static void main(String[] args) { Graph graph = new Graph(GRAPH); graph.dijkstra(START); System.out.println(graph.getPath(END)); } static class Graph { private final Map<String, Vertex> graph; static class Edge { final String v1, v2; final int dist; Edge(String v1, String v2, int dist) { this.v1 = v1; this.v2 = v2; this.dist = dist; } } static class Vertex implements Comparable<Vertex> { final String name; int dist = Integer.MAX_VALUE; Vertex previous = null; final Map<Vertex, Integer> neighbours = new HashMap<>(); Vertex(String name) { this.name = name; } private void printPath() { if (this == this.previous) { System.out.printf("%s", this.name); } else if (this.previous == null) { System.out.printf("%s(unreached)", this.name); } else { this.previous.printPath(); System.out.printf(" -> %s(%d)", this.name, this.dist); } } public int compareTo(Vertex other) { return Integer.compare(dist, other.dist); } } Graph(Edge[] edges) { graph = new HashMap<>(edges.length); for (Edge e : edges) { if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1)); if (!graph.containsKey(e.v2)) graph.put(e.v2, new Vertex(e.v2)); } for (Edge e : edges) { graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist); } } void dijkstra(String startName) { if (!graph.containsKey(startName)) { System.err.printf("Graph doesn't contain start vertex \"%s\"\n", startName); return; } final Vertex source = graph.get(startName); NavigableSet<Vertex> q = new TreeSet<>(); for (Vertex v : graph.values()) { v.previous = v == source ? source : null; v.dist = v == source ? 0 : Integer.MAX_VALUE; q.add(v); } dijkstra(q); } private void dijkstra(final NavigableSet<Vertex> q) { Vertex u, v; while (!q.isEmpty()) { u = q.pollFirst(); if (u.dist == Integer.MAX_VALUE) break; for (Map.Entry<Vertex, Integer> a : u.neighbours.entrySet()) { v = a.getKey(); final int alternateDist = u.dist + a.getValue(); if (alternateDist < v.dist) { q.remove(v); v.dist = alternateDist; v.previous = u; q.add(v); } } } } public List<String> getPath(String endName) { if (!graph.containsKey(endName)) { System.err.printf("Graph doesn't contain end vertex \"%s\"\n", endName); return Collections.emptyList(); } return graph.get(endName).printPath(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值