- 魔法城市
时间限制
:
(每个
case
)
2s
空间限制:
128MB
小
Q
来到一个魔法王国,这个王国一共有
n
个城市,分别是
0~n-1
号魔法城市,任意两个城市都有一条魔法通道连通(无向边),每条魔法通道都需要一定的时间才能通过。小
Q
现在在
0
号城市,他希望通过穿梭魔法通道到达
1
号魔法城市。
小
Q
为了更快到达
1
号魔法城市在魔法商店购买了一把魔力扫把,使用魔力扫把在一条魔法通道飞行的时候可以让该条魔法通道话费的时间减半,但是魔法扫把最多只能使用
k
次,小
Q
想知道他从
0
号魔法城市到
1
号魔法城市需要多少时间。
输入:
输入包括
n+1
行。
第一行中有两个正整数
n, k(2<=n<=50, 0<=k<=50)
,分别代表城市数量和魔力扫把可以使用的次数,以空格分割。
接下类
n
行,每行一个长度为
n
的字符串
dis[i], dis[i][j](‘0’<=dis[i][j]<=’9’)
表示从
i
号魔法城市到
j
号魔法城市需要的时间。
对于所有合法的
i
和
j
满足
dis[i][j]=dis[j][i]
对于合法的
i
满足
dis[i] = 0
输出:
输出一个实数表示小
Q
从
0
号魔法城市到
1
号魔法城市最少需要的时间,答案保留
1
位小数。
【请注意:
javascrip
语言不支持调试,请同学们优先考虑使用其他语言,谢谢】
样例输入:
3 2
094
904
440
样例输出:
4.0
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
public class TencentMagicCity {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
str = br.readLine().trim();
int start = str.trim().indexOf(" ");
int end = str.trim().lastIndexOf(" ");
String str1 = str.substring(0,start);
String str2 = str.substring(end+1,str.length());
int n = Integer.parseInt(str1);
int k = Integer.parseInt(str2);
int[][] dis = new int[n][n];
for(int i=0;i<n;i++){
String value = br.readLine().trim();
for(int j = 0;j<value.length();j++){
dis[i][j] = Integer.parseInt(String.valueOf(value.charAt(j)));
}
}
float maxTime = 2^32;
//链表的每个元素存储着单一通路的行走时间,遍历链表中的元素
ArrayList<int[]> arr = magicCity(n,dis);
// for(Iterator<int[]> iterator = arr.iterator();iterator.hasNext();){
// int[] temp = iterator.next();
// for(int i = 0;i<temp.length;i++){
// System.out.print(temp[i]+" ");
// }
// System.out.println();
// }
//遍历链表中的元素,打印所需时间最少的通路所用时间
for(Iterator<int[]> iterator = arr.iterator();iterator.hasNext();){
int[] temp = iterator.next();
sortTime(temp,0,temp.length-1);
float realTime = 0;
if(k>=temp.length){
for(int i =0;i<temp.length;i++){
realTime += temp[i]/2;
}
}else {
for(int i=0;i<k;i++){
realTime += temp[i]/2;
}
for(int i=k;i<temp.length;i++){
realTime += temp[i];
}
}
if(realTime<maxTime) maxTime = realTime;
}
System.out.println(maxTime);
}
private static ArrayList<int[]> magicCity(int cityNum, int[][] dis) {
ArrayList<int[]> arr = new ArrayList<int[]>();
ArrayList<String> arr_temp = new ArrayList<String>();
String[] cities = new String[cityNum];
for(int i = 0;i<cityNum;i++){
cities[i] = Integer.toString(i);
}
arr_temp.add(cities[0]);
magicCity(cities,dis,arr,arr_temp);
return arr;
}
private static void magicCity(String[] cities, int[][] dis, ArrayList<int[]> arr, ArrayList<String> arr_temp) {
if(arr_temp.contains(cities[1])){ //递归结束,到达城市1
int[] temp = new int[arr_temp.size()-1];
for(int k = 0;k<arr_temp.size()-1;k++){
int m = Integer.parseInt(arr_temp.get(k));
int n = Integer.parseInt(arr_temp.get(k+1));
temp[k] = dis[m][n];
}
arr.add(temp);
return;
}
for (int i = 0;i<cities.length;i++){
if(!arr_temp.contains(cities[i])){
arr_temp.add(cities[i]);
magicCity(cities,dis,arr,arr_temp);
arr_temp.remove(arr_temp.size()-1);
}
}
}
public static void sortTime(int[] arr,int p,int q)
{
if (p < q) {
int i = Partition(arr,p,q);
sortTime(arr,p,i-1);
sortTime(arr,i+1,q);
}
}
public static int Partition(int[] arr,int p,int q)
{
int x = arr[p];
int i = p;
for (int j = p+1; j <= q; j++) {
if (arr[j] > x ) {
i = i+1;
Swap(arr,i,j);
}
}
Swap(arr,p,i);
return i;
}
public static void Swap(int[] arr,int m,int n)
{
int temp;
temp = arr[m];
arr[m]=arr[n];
arr[n]=temp;
}
}
参考:http://blog.csdn.net/wjheha/article/details/77984631
改正其输出错误
public class Dijkstra2 {
static int M=10000;//(此路不通)
public static void main(String[] args) {
int[][] weight1 = {//邻接矩阵
{0,3,M,7,M},
{3,0,4,2,M},
{M,4,0,5,4},
{7,2,5,0,6},
{M,M,4,6,0}
};
int[][] weight2 = {
{0,10,M,30,100},
{M,0,50,M,M},
{M,M,0,M,10},
{M,M,20,0,60},
{M,M,M,M,0}
};
int[][] weight3 ={
{0, 6, 3, M, M, M},
{6, 0, 2, 5, M, M},
{3, 2, 0, 3, 4, M},
{M, 5, 3, 0, 2, 3},
{M, M, 4, 2, 0, 5},
{M, M, M, 3, 5, 0}
};
int[][] weight4 = {
{0, 9, 4},
{9, 0, 4},
{4, 4, 0}
};
int start=0;
int[] shortPath = Dijsktra(weight1,start);
for(int i = 0;i < shortPath.length;i++)
System.out.println("从"+start+"出发到"+i+"的最短距离为:"+shortPath[i]);
}
public static int[] Dijsktra(int[][] weight,int start){
//接受一个有向图的权重矩阵,和一个起点编号start(从0编号,顶点存在数组中)
//返回一个int[] 数组,表示从start到它的最短路径长度
int n = weight.length; //顶点个数
int[] shortPath = new int[n]; //存放从start到其他各点的最短路径
String[] path=new String[n]; //存放从start到其他各点的最短路径的字符串表示
for(int i=0;i<n;i++)
path[i]=new String(start+"-->"+i);
int[] visited = new int[n]; //标记当前该顶点的最短路径是否已经求出,1表示已求出
//初始化,第一个顶点求出
shortPath[start] = 0;
visited[start] = 1;
for(int count = 1;count <= n - 1;count++) //要加入n-1个顶点
{
int k = -1; //选出一个距离初始顶点start最近的未标记顶点
int dmin = Integer.MAX_VALUE;
for(int i = 0;i < n;i++)
{
if(visited[i] == 0 && weight[start][i] < dmin)
{
dmin = weight[start][i];
k = i;
}
}
//将新选出的顶点标记为已求出最短路径,且到start的最短路径就是dmin
shortPath[k] = dmin;
visited[k] = 1;
//以k为中间点,修正从start到未访问各点的距离
for(int i = 0;i < n;i++)
{
if(visited[i] == 0 && weight[start][k] + weight[k][i] < weight[start][i]){
weight[start][i] = weight[start][k] + weight[k][i];
path[i]=path[k]+"-->"+i;
}
}
}
for(int i=0;i<n;i++)
System.out.println("从"+start+"出发到"+i+"的最短路径为:"+path[i]);
System.out.println("=====================================");
return shortPath;
}
}
参考:http://128kj.iteye.com/blog/1678532