您的位置:首页 > 其它

URAL 1205 By the Underground or by Foot (建图 + Dijkstra + 堆优化)

2015-09-29 09:15 597 查看
#include <stdio.h>
#include <math.h>
#define INF (1 << 30)

double footSpeed, undergroundSpeed;
int numOfStations;
int start, end;
typedef struct Coordinates{
double x;
double y;
}Cooridnates;
Coordinates CoordinatesArray[300];
double timeArray[300][300];
double minTimeArray[300];
int stack[300];
int top;
int pre[300];
int heapSize;
typedef struct Node{
double minTime;
int location;
}Node;
Node heap[300];

double getDistance(Coordinates one, Coordinates another){
double deltaX = one.x - another.x;
double deltaY = one.y - another.y;
return sqrt(deltaX * deltaX + deltaY * deltaY);
}

void swap(Node *a, Node *b){
Node c = *a;
*a = *b;
*b = c;
}

void heapDecreaseKey(int NodeIndex,double minTime){
heap[NodeIndex].minTime = minTime;
while (NodeIndex > 1 && heap[NodeIndex].minTime < heap[ NodeIndex >> 1 ].minTime){
swap(&heap[NodeIndex], &heap[ NodeIndex >> 1 ]);
NodeIndex = NodeIndex >> 1;
}
}

void minHeapify(int parent){
int least = parent;
int left = parent << 1;
if (left <= heapSize && heap[left].minTime < heap[least].minTime)
least = left;
int right = (parent << 1) + 1;
if (right <= heapSize && heap[right].minTime < heap[least].minTime)
least = right;
if (least != parent){
swap(&heap[parent], &heap[least]);
minHeapify(least);
}
}

void buildMinHeap(){
int to;
for (to = heapSize >> 1; to >= 1; to--)
minHeapify(to);
}

double getMinTimeByDijkstra(){
heapSize = 0;
int to;
for (to = 1; to <= end; to++){
if (to != start){
heapSize++;
heap[heapSize].minTime = timeArray[start][to];
heap[heapSize].location = to;
}
}

buildMinHeap();

int numOfMinTimesFound;
for (numOfMinTimesFound = 2; numOfMinTimesFound <= end; numOfMinTimesFound){
double minTime = heap[1].minTime;
int location = heap[1].location;
if (location == end)
return minTime;
swap(&heap[1], &heap[heapSize]);
heapSize--;
int NodeIndex;
for (NodeIndex = 1; NodeIndex <= heapSize; NodeIndex++){
Node tempNode = heap[NodeIndex];
if (minTime + timeArray[location][tempNode.location] < tempNode.minTime){
heapDecreaseKey(NodeIndex, minTime + timeArray[location][tempNode.location]);
pre[tempNode.location] = location;
}
}
minHeapify(1);
}

}

int main(){

scanf("%lf%lf", &footSpeed, &undergroundSpeed);

scanf("%d", &numOfStations);
int station;
for (station = 1; station <= numOfStations; station++){
Coordinates tempCoordinates;
scanf("%lf%lf", &tempCoordinates.x, &tempCoordinates.y);
CoordinatesArray[station] = tempCoordinates;
}

int from, to;
for (from = 1; from <= numOfStations; from++)
for (to = from + 1; to <= numOfStations; to++)
//注意:默认可以从一个车站步行到另一个车站
timeArray[from][to] = timeArray[to][from] = getDistance(CoordinatesArray[from], CoordinatesArray[to]) / footSpeed;

while (scanf("%d%d", &from, &to) != EOF && (from != 0 && to != 0) )
timeArray[from][to] = timeArray[to][from] = getDistance(CoordinatesArray[from], CoordinatesArray[to]) / undergroundSpeed;

start = numOfStations + 1;
end = numOfStations + 2;
scanf("%lf%lf", &CoordinatesArray[start].x, &CoordinatesArray[start].y);
scanf("%lf%lf", &CoordinatesArray[end].x, &CoordinatesArray[end].y);
int location;
for (location = 1; location <= end; location++){
timeArray[start][location] = timeArray[location][start] = getDistance(CoordinatesArray[start], CoordinatesArray[location]) / footSpeed;
timeArray[end][location] = timeArray[location][end] = getDistance(CoordinatesArray[end], CoordinatesArray[location]) / footSpeed;
}

//注意输出精度
printf("%.10lf\n", getMinTimeByDijkstra());

int preLocation = pre[end];
while (preLocation != 0){
stack[++top] = preLocation;
preLocation = pre[preLocation];
}

printf("%d", top);
while (top > 0)
printf(" %d", stack[top--]);
printf("\n");

return 0;
}




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息