07-图5 Saving James Bond - Hard Version(C)

 哈哈,我是真的服了,写了好几天结果给我个这,气死我了,果然还有很大的进步空间。如果有c测试点4,就好了。 又写了一天,是真解决不了了,这个问题等我明白一定来解答

哈哈,

测试点提示内存(KB)用时(ms)结果得分
0sample1 多条最短路,同一点有多路,最近点无路,多连通1841

答案正确

15 / 15
1sample 2 聚集型,均离岸远3641

答案正确

3 / 3
2分散型,均跳不到,有在角上3561

答案正确

2 / 2
3有一只在岸上,有一只在岛上,不能算在内3162

答案正确

3 / 3
4最大N,sample1的复杂版,可选路径8条,后面要更新前面的最短路3082

答案错误

0 / 6
5最小N,一步跳到岸3002

答案正确

1 / 1
题目大致信息。

This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was captured by a group of drug dealers. He was sent to a small piece of land at the center of a lake filled with crocodiles. There he performed the most daring action to escape -- he jumped onto the head of the nearest crocodile! Before the animal realized what was happening, James jumped again onto the next big head... Finally he reached the bank before the last crocodile could bite him (actually the stunt man was caught by the big mouth and barely escaped with his extra thick boot).

Assume that the lake is a 100 by 100 square one. Assume that the center of the lake is at (0,0) and the northeast corner at (50,50). The central island is a disk centered at (0,0) with the diameter of 15. A number of crocodiles are in the lake at various positions. Given the coordinates of each crocodile and the distance that James could jump, you must tell him a shortest path to reach one of the banks. The length of a path is the number of jumps that James has to make.

Input Specification:

Each input file contains one test case. Each case starts with a line containing two positive integers N (≤100), the number of crocodiles, and D, the maximum distance that James could jump. Then N lines follow, each containing the (x,y) location of a crocodile. Note that no two crocodiles are staying at the same position.

Output Specification:

For each test case, if James can escape, output in one line the minimum number of jumps he must make. Then starting from the next line, output the position (x,y) of each crocodile on the path, each pair in one line, from the island to the bank. If it is impossible for James to escape that way, simply give him 0 as the number of jumps. If there are many shortest paths, just output the one with the minimum first jump, which is guaranteed to be unique.

Sample Input 1:

17 15
10 -21
10 21
-40 10
30 -50
20 40
35 10
0 -10
-25 22
40 -40
-30 30
-10 22
0 11
25 21
25 10
10 10
10 35
-30 10

Sample Output 1:

4
0 11
10 21
10 35

Sample Input 2:

4 13
-12 12
12 12
-12 -12
12 -12

Sample Output 2:

0

虽然我不是满分,问题也暂时解决不了,但不妨碍他是一个较好的代码,可以看一下,开头的运行速度,哈哈。毕竟我们相遇必定是为了学习数据结构而来,所以加油。

我的代码主要分为4各部分

首先我先展示头文件,与主函数

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<math.h>int main()
{LGraph M;Point *Array;bool *Visited;M = Init_Graph();Array = Read_Point_Array(M ->N);Visited = (bool*)calloc(M ->N + 1, sizeof(bool));M = Build_Graph(M, Array, Visited);if(M){double *dist;int *path;int Node;Stack S;dist = (double*)malloc(sizeof(double) * (M ->N + 1));path = (int*)malloc(sizeof(int) * (M ->N + 1));Dijkstra(M, dist, path);Node = Fllush_Mindata(M, Visited, dist, path);S = Init_Stack();Push_path_data(S, path, Node);Print_Path(S, Array);}	return 0;
}

第一部分,构造图并插入数据

const double INFITY = 500000.0;typedef struct Coordinate *Point;
struct Coordinate{int X;int Y;
};typedef struct ENode *PtrToENode;
typedef PtrToENode Edge;
struct ENode{int V1, V2;double dist;	
};typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{int V;double dist;PtrToAdjVNode Next;	
};typedef struct VNode **AdjList;
struct VNode{PtrToAdjVNode FirstEdge;	
};typedef struct GNode *LGraph;
struct GNode{int N;double D;AdjList G;
};LGraph Build_Graph(LGraph M, Point *Array, bool *Visited);
LGraph Init_Graph();
Point* Read_Point_Array(int N);
bool Up_ashore(Point P, double D);
double Dict_E(Point start, Point end, double D);
void Insert_Graph(LGraph M, Edge E);
LGraph Init_Graph()
{LGraph M;M = (LGraph)malloc(sizeof(struct GNode));scanf("%d %lf", &M ->N, &M ->D);M ->G = (AdjList)malloc(sizeof(struct VNode) * (M ->N + 1));for(int i = 0; i <= M ->N; i++){M ->G[i] = (struct VNode*)malloc(sizeof(struct VNode));M ->G[i] ->FirstEdge = NULL;}return M;
}Point* Read_Point_Array(int N)
{Point *Array;Array = (Point*)malloc(sizeof(Point) * (N + 1));Array[0] = (Point)malloc(sizeof(struct Coordinate));Array[0] ->X = 0;Array[0] ->Y = 0;for(int i = 1; i <= N; i++){Array[i] = (Point)malloc(sizeof(struct Coordinate));scanf("%d %d", &(Array[i] ->X), &(Array[i] ->Y));}return Array;
}LGraph Build_Graph(LGraph M, Point *Array, bool *Visited)
{Edge E;bool Up = false;bool Up_D = false;E = (Edge)malloc(sizeof(struct ENode));if(Up_ashore(Array[0], M ->D + 7.5)){printf("1\n");return NULL;}for(int i = 1; i <= M ->N; i++){if(Up_ashore(Array[i], M ->D + 7.5)){Visited[i] = true;Up = true;}E ->dist = Dict_E(Array[0], Array[i], M ->D + 7.5);E ->V1 = 0;E ->V2 = i;if(E ->dist != 0 && E ->dist > 7.5){Up_D = true;Insert_Graph(M, E);}}if(!Up || !Up_D){printf("0\n");return NULL;}for(int i = 1; i <= M ->N; i++){for(int j = i + 1; j <= M ->N; j++){E ->dist = Dict_E(Array[i], Array[j], M ->D);E ->V1 = i;E ->V2 = j;if(E ->dist != 0){Insert_Graph(M, E);}}	}return M;
}void Insert_Graph(LGraph M, Edge E)
{PtrToAdjVNode NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V2;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V1] ->FirstEdge;M ->G[E ->V1] ->FirstEdge = NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V1;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V2] ->FirstEdge;M ->G[E ->V2] ->FirstEdge = NewNode;
}
double Dict_E(Point start, Point end, double D)
{double dis;dis = sqrt(pow(start ->X - end ->X, 2) + pow(start ->Y - end ->Y, 2));if(dis <= D){return dis;}else{return 0;}
}
bool Up_ashore(Point P, double D)
{return (abs(P ->X) >= 50 - D || abs(P ->Y) >= 50 - D);
}

第二部分,构建堆

typedef struct HeapNode *HN;
struct HeapNode{int sign;double dist;
};typedef struct Heap *MinHeap;
struct Heap{HN data;int Size;
};MinHeap Init_dist(LGraph M);
void Insert_Heap(MinHeap H, double Data, int sign);
struct HeapNode Delete_Heap(MinHeap H);
void Creat_Heap(int head, LGraph M, MinHeap H, bool *collected);void Creat_Heap(int head, LGraph M, MinHeap H, bool *collected)
{PtrToAdjVNode G;for(G = M ->G[head] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V]){Insert_Heap(H, G ->dist, G ->V);}}
}void Insert_Graph(LGraph M, Edge E)
{PtrToAdjVNode NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V2;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V1] ->FirstEdge;M ->G[E ->V1] ->FirstEdge = NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V1;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V2] ->FirstEdge;M ->G[E ->V2] ->FirstEdge = NewNode;
}MinHeap Init_dist(LGraph M)
{MinHeap dist;dist = (MinHeap)malloc(sizeof(struct Heap) * (M ->N + 1));dist->data = (HN)malloc(sizeof(struct HeapNode) * (M ->N + 1));dist ->Size = 0;dist ->data[0].sign = -1;dist ->data[0].dist = -1;return dist;
}
void Insert_Heap(MinHeap H, double Data, int sign)
{int i;i = ++(H ->Size);for(; Data < H ->data[i/2].dist; i /= 2){H ->data[i].dist = H ->data[i/2].dist;H ->data[i].sign = H ->data[i/2].sign;}H ->data[i].dist = Data;H ->data[i].sign = sign;
}
struct HeapNode Delete_Heap(MinHeap H)
{int Child, Parent;struct HeapNode Min, Temp;if(H ->Size == 0){return H ->data[0];}Min = H ->data[1];Temp = H ->data[H ->Size --];for(Parent = 1; Parent * 2 <= H ->Size; Parent = Child){Child = Parent * 2;if((Child != H ->Size) && H ->data[Child].dist > H ->data[Child + 1].dist){Child++;}if(Temp.dist <= H ->data[Child].dist){break;}else{H ->data[Parent].dist = H ->data[Child].dist;H ->data[Parent].sign = H ->data[Child].sign;}	}H ->data[Parent].dist = Temp.dist;H ->data[Parent].sign = Temp.sign;return Min;
}

第三部分,Dijkstra算法,与寻求路径

void Dijkstra(LGraph M, double *dist, int *path)
{MinHeap H;struct HeapNode HNode;bool *collected;PtrToAdjVNode G;H = Init_dist(M);collected = (bool*)malloc(sizeof(bool) * (M ->N + 1));Init_DP(dist, path, M ->N);Creat_Heap(0, M, H, collected);dist[0] = 0;collected[0] = true;while(HNode = Delete_Heap(H), HNode.sign != -1){collected[HNode.sign] = true;if(dist[HNode.sign] > HNode.dist){dist[HNode.sign] = HNode.dist;path[HNode.sign] = 0;}for(G = M ->G[HNode.sign] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V] && dist[G ->V] > dist[HNode.sign] + G ->dist){dist[G ->V] = dist[HNode.sign] +  G ->dist;path[G ->V] = HNode.sign;Insert_Heap(H, dist[G ->V], G ->V);}}	}
}void Init_DP(double *dist, int *path, int N)
{for(int i = 0; i <= N; i++){dist[i] = INFITY;path[i] = -1;}
}

第四部分,求取最小路径,巧用堆栈

typedef struct Node *Stack;
struct Node{int data;Stack Next;
};bool Find_Root(int *path, int N);
int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path);
Stack Init_Stack();
void Push_Stack(Stack S, int data);
int Pop_Stack(Stack S);
bool IsEmpty(Stack S);
void Push_path_data(Stack S,  int *path, int Node);
void Print_Path(Stack S, Point *Array);void Print_Path(Stack S, Point *Array)
{int Node;printf("%d\n", S ->data);while(!IsEmpty(S)){Node = Pop_Stack(S);printf("%d %d\n", Array[Node] ->X, Array[Node] ->Y);}
}
void Push_path_data(Stack S,  int *path, int Node)
{if(Node == 0){return ;}if(Node != 0){Push_Stack(S, Node);S ->data++;}Push_path_data(S, path, path[Node]);
}
int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path)
{int N, Node;int Cycle;int MinCycle = (int)INFITY;double dmin = INFITY;double MinJump;int MinSkip;for(int i = 1; i <= M ->N; i++){Cycle = 0;if(Visited[i] && Find_Root(path, i)){N = i;while(N != 0){if(path[N] == 0){MinSkip = N;}N = path[N];Cycle++;}if(Cycle == MinCycle){if(dist[i] < dmin){Node = i;}if(dist[i] == dmin){if(dist[MinSkip] < MinJump){Node = i;}}}if(Cycle < MinCycle){dmin = dist[i];MinJump = dist[MinSkip];MinCycle = Cycle;Node = i;	}}}return Node;
}
bool Find_Root(int *path, int N)
{if(N == 0){return true;}if(N == -1){return  false;}return Find_Root(path, path[N]);
}Stack Init_Stack()
{Stack S;S = (Stack)malloc(sizeof(struct Node));S ->data = 1;S ->Next = NULL;return S;
}
void Push_Stack(Stack S, int data)
{Stack T;T = (Stack)malloc(sizeof(struct Node));T ->data = data;T ->Next = S ->Next;S ->Next = T;
}
int Pop_Stack(Stack S)
{int temp;Stack Top;if(IsEmpty(S)){printf("IS Empty the Stack!\n");return -1;}else{Top = S ->Next;S ->Next = Top ->Next;temp = Top ->data;free(Top);return temp;}
}
bool IsEmpty(Stack S)
{return (S->Next == NULL);
}

我的全部AC:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<math.h>const double INFITY = 500000.0;typedef struct Coordinate *Point;
struct Coordinate{int X;int Y;
};typedef struct ENode *PtrToENode;
typedef PtrToENode Edge;
struct ENode{int V1, V2;double dist;	
};typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{int V;double dist;PtrToAdjVNode Next;	
};typedef struct VNode **AdjList;
struct VNode{PtrToAdjVNode FirstEdge;	
};typedef struct GNode *LGraph;
struct GNode{int N;double D;AdjList G;
};typedef struct HeapNode *HN;
struct HeapNode{int sign;double dist;
};typedef struct Heap *MinHeap;
struct Heap{HN data;int Size;
};typedef struct Node *Stack;
struct Node{int data;Stack Next;
};LGraph Build_Graph(LGraph M, Point *Array, bool *Visited);
LGraph Init_Graph();
Point* Read_Point_Array(int N);
bool Up_ashore(Point P, double D);
double Dict_E(Point start, Point end, double D);
void Insert_Graph(LGraph M, Edge E);
MinHeap Init_dist(LGraph M);
void Insert_Heap(MinHeap H, double Data, int sign);
struct HeapNode Delete_Heap(MinHeap H);
void Creat_Heap(int head, LGraph M, MinHeap H, bool *collected);
void Init_DP(double *dist, int *path, int N);
void Dijkstra(LGraph M, double *dist, int *path);
bool Find_Root(int *path, int N);
int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path);
Stack Init_Stack();
void Push_Stack(Stack S, int data);
int Pop_Stack(Stack S);
bool IsEmpty(Stack S);
void Push_path_data(Stack S,  int *path, int Node);
void Print_Path(Stack S, Point *Array);int main()
{LGraph M;Point *Array;bool *Visited;M = Init_Graph();Array = Read_Point_Array(M ->N);Visited = (bool*)calloc(M ->N + 1, sizeof(bool));M = Build_Graph(M, Array, Visited);if(M){double *dist;int *path;int Node;Stack S;dist = (double*)malloc(sizeof(double) * (M ->N + 1));path = (int*)malloc(sizeof(int) * (M ->N + 1));Dijkstra(M, dist, path);Node = Fllush_Mindata(M, Visited, dist, path);S = Init_Stack();Push_path_data(S, path, Node);Print_Path(S, Array);}	return 0;
}
void Print_Path(Stack S, Point *Array)
{int Node;printf("%d\n", S ->data);while(!IsEmpty(S)){Node = Pop_Stack(S);printf("%d %d\n", Array[Node] ->X, Array[Node] ->Y);}
}
void Push_path_data(Stack S,  int *path, int Node)
{if(Node == 0){return ;}if(Node != 0){Push_Stack(S, Node);S ->data++;}Push_path_data(S, path, path[Node]);
}
int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path)
{int N, Node;int Cycle;int MinCycle = (int)INFITY;double dmin = INFITY;double MinJump;int MinSkip;for(int i = 1; i <= M ->N; i++){Cycle = 0;if(Visited[i] && Find_Root(path, i)){N = i;while(N != 0){if(path[N] == 0){MinSkip = N;}N = path[N];Cycle++;}if(Cycle == MinCycle){if(dist[i] < dmin){Node = i;}if(dist[i] == dmin){if(dist[MinSkip] < MinJump){Node = i;}}}if(Cycle < MinCycle){dmin = dist[i];MinJump = dist[MinSkip];MinCycle = Cycle;Node = i;	}}}return Node;
}
bool Find_Root(int *path, int N)
{if(N == 0){return true;}if(N == -1){return  false;}return Find_Root(path, path[N]);
}
LGraph Build_Graph(LGraph M, Point *Array, bool *Visited)
{Edge E;bool Up = false;bool Up_D = false;E = (Edge)malloc(sizeof(struct ENode));if(Up_ashore(Array[0], M ->D + 7.5)){printf("1\n");return NULL;}for(int i = 1; i <= M ->N; i++){if(Up_ashore(Array[i], M ->D + 7.5)){Visited[i] = true;Up = true;}E ->dist = Dict_E(Array[0], Array[i], M ->D + 7.5);E ->V1 = 0;E ->V2 = i;if(E ->dist != 0 && E ->dist > 7.5){Up_D = true;Insert_Graph(M, E);}}if(!Up || !Up_D){printf("0\n");return NULL;}for(int i = 1; i <= M ->N; i++){for(int j = i + 1; j <= M ->N; j++){E ->dist = Dict_E(Array[i], Array[j], M ->D);E ->V1 = i;E ->V2 = j;if(E ->dist != 0){Insert_Graph(M, E);}}	}return M;
}
void Dijkstra(LGraph M, double *dist, int *path)
{MinHeap H;struct HeapNode HNode;bool *collected;PtrToAdjVNode G;H = Init_dist(M);collected = (bool*)malloc(sizeof(bool) * (M ->N + 1));Init_DP(dist, path, M ->N);Creat_Heap(0, M, H, collected);dist[0] = 0;collected[0] = true;while(HNode = Delete_Heap(H), HNode.sign != -1){collected[HNode.sign] = true;if(dist[HNode.sign] > HNode.dist){dist[HNode.sign] = HNode.dist;path[HNode.sign] = 0;}for(G = M ->G[HNode.sign] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V] && dist[G ->V] > dist[HNode.sign] + G ->dist){dist[G ->V] = dist[HNode.sign] +  G ->dist;path[G ->V] = HNode.sign;Insert_Heap(H, dist[G ->V], G ->V);}}	}
}void Init_DP(double *dist, int *path, int N)
{for(int i = 0; i <= N; i++){dist[i] = INFITY;path[i] = -1;}
}
void Creat_Heap(int head, LGraph M, MinHeap H, bool *collected)
{PtrToAdjVNode G;for(G = M ->G[head] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V]){Insert_Heap(H, G ->dist, G ->V);}}
}void Insert_Graph(LGraph M, Edge E)
{PtrToAdjVNode NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V2;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V1] ->FirstEdge;M ->G[E ->V1] ->FirstEdge = NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V1;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V2] ->FirstEdge;M ->G[E ->V2] ->FirstEdge = NewNode;
}LGraph Init_Graph()
{LGraph M;M = (LGraph)malloc(sizeof(struct GNode));scanf("%d %lf", &M ->N, &M ->D);M ->G = (AdjList)malloc(sizeof(struct VNode) * (M ->N + 1));for(int i = 0; i <= M ->N; i++){M ->G[i] = (struct VNode*)malloc(sizeof(struct VNode));M ->G[i] ->FirstEdge = NULL;}return M;
}Point* Read_Point_Array(int N)
{Point *Array;Array = (Point*)malloc(sizeof(Point) * (N + 1));Array[0] = (Point)malloc(sizeof(struct Coordinate));Array[0] ->X = 0;Array[0] ->Y = 0;for(int i = 1; i <= N; i++){Array[i] = (Point)malloc(sizeof(struct Coordinate));scanf("%d %d", &(Array[i] ->X), &(Array[i] ->Y));}return Array;
}
double Dict_E(Point start, Point end, double D)
{double dis;dis = sqrt(pow(start ->X - end ->X, 2) + pow(start ->Y - end ->Y, 2));if(dis <= D){return dis;}else{return 0;}
}
bool Up_ashore(Point P, double D)
{return (abs(P ->X) >= 50 - D || abs(P ->Y) >= 50 - D);
}MinHeap Init_dist(LGraph M)
{MinHeap dist;dist = (MinHeap)malloc(sizeof(struct Heap) * (M ->N + 1));dist->data = (HN)malloc(sizeof(struct HeapNode) * (M ->N + 1));dist ->Size = 0;dist ->data[0].sign = -1;dist ->data[0].dist = -1;return dist;
}
void Insert_Heap(MinHeap H, double Data, int sign)
{int i;i = ++(H ->Size);for(; Data < H ->data[i/2].dist; i /= 2){H ->data[i].dist = H ->data[i/2].dist;H ->data[i].sign = H ->data[i/2].sign;}H ->data[i].dist = Data;H ->data[i].sign = sign;
}
struct HeapNode Delete_Heap(MinHeap H)
{int Child, Parent;struct HeapNode Min, Temp;if(H ->Size == 0){return H ->data[0];}Min = H ->data[1];Temp = H ->data[H ->Size --];for(Parent = 1; Parent * 2 <= H ->Size; Parent = Child){Child = Parent * 2;if((Child != H ->Size) && H ->data[Child].dist > H ->data[Child + 1].dist){Child++;}if(Temp.dist <= H ->data[Child].dist){break;}else{H ->data[Parent].dist = H ->data[Child].dist;H ->data[Parent].sign = H ->data[Child].sign;}	}H ->data[Parent].dist = Temp.dist;H ->data[Parent].sign = Temp.sign;return Min;
}Stack Init_Stack()
{Stack S;S = (Stack)malloc(sizeof(struct Node));S ->data = 1;S ->Next = NULL;return S;
}
void Push_Stack(Stack S, int data)
{Stack T;T = (Stack)malloc(sizeof(struct Node));T ->data = data;T ->Next = S ->Next;S ->Next = T;
}
int Pop_Stack(Stack S)
{int temp;Stack Top;if(IsEmpty(S)){printf("IS Empty the Stack!\n");return -1;}else{Top = S ->Next;S ->Next = Top ->Next;temp = Top ->data;free(Top);return temp;}
}
bool IsEmpty(Stack S)
{return (S->Next == NULL);
}

 下面是我的测试代码,后期我会在刷新数据,参考我上述的全部代码。

主要是,之前为了解决问题搞得测试代码,现在是真服了,我解决

 有朋友问,后面的跟新前面的最短路径,这是我的测试更新,以及具体点位。


dist[1] : dist[7] + E(1 -> 7)
500000.000000 : 10.000000 + 14.866069更新完成!
dist[1] : dist[7] + E(1 -> 7)
24.866069 : 10.000000 + 14.866069dist[15] : dist[12] + E(15 -> 12)
500000.000000 : 11.000000 + 10.049876更新完成!
dist[15] : dist[12] + E(15 -> 12)
21.049876 : 11.000000 + 10.049876dist[11] : dist[12] + E(11 -> 12)
500000.000000 : 11.000000 + 14.866069更新完成!
dist[11] : dist[12] + E(11 -> 12)
25.866069 : 11.000000 + 14.866069dist[2] : dist[12] + E(2 -> 12)
500000.000000 : 11.000000 + 14.142136更新完成!
dist[2] : dist[12] + E(2 -> 12)
25.142136 : 11.000000 + 14.142136dist[14] : dist[15] + E(14 -> 15)
500000.000000 : 14.142136 + 15.000000更新完成!
dist[14] : dist[15] + E(14 -> 15)
29.142136 : 14.142136 + 15.000000dist[2] : dist[15] + E(2 -> 15)
25.142136 : 14.142136 + 11.000000dist[14] : dist[15] + E(14 -> 15)
29.142136 : 14.142136 + 15.000000dist[2] : dist[15] + E(2 -> 15)
25.142136 : 14.142136 + 11.000000dist[16] : dist[2] + E(16 -> 2)
500000.000000 : 25.142136 + 14.000000更新完成!
dist[16] : dist[2] + E(16 -> 2)
39.142136 : 25.142136 + 14.000000dist[13] : dist[2] + E(13 -> 2)
500000.000000 : 25.142136 + 15.000000更新完成!
dist[13] : dist[2] + E(13 -> 2)
40.142136 : 25.142136 + 15.000000dist[8] : dist[11] + E(8 -> 11)
500000.000000 : 25.866069 + 15.000000更新完成!
dist[8] : dist[11] + E(8 -> 11)
40.866069 : 25.866069 + 15.000000dist[13] : dist[14] + E(13 -> 14)
40.142136 : 29.142136 + 11.000000dist[6] : dist[14] + E(6 -> 14)
500000.000000 : 29.142136 + 10.000000更新完成!
dist[6] : dist[14] + E(6 -> 14)
39.142136 : 29.142136 + 10.000000dist[5] : dist[16] + E(5 -> 16)
500000.000000 : 39.142136 + 11.180340更新完成!
dist[5] : dist[16] + E(5 -> 16)
50.322476 : 39.142136 + 11.180340dist[13] : dist[6] + E(13 -> 6)
40.142136 : 39.142136 + 14.866069dist[17] : dist[8] + E(17 -> 8)
500000.000000 : 40.866069 + 13.000000更新完成!
dist[17] : dist[8] + E(17 -> 8)
53.866069 : 40.866069 + 13.000000dist[10] : dist[8] + E(10 -> 8)
500000.000000 : 40.866069 + 9.433981更新完成!
dist[10] : dist[8] + E(10 -> 8)
50.300050 : 40.866069 + 9.433981dist[3] : dist[17] + E(3 -> 17)
500000.000000 : 53.866069 + 10.000000更新完成!
dist[3] : dist[17] + E(3 -> 17)
63.866069 : 53.866069 + 10.000000
Visited[0] = 0  dist[0] = 0.000000      path[0] = -1
Visited[1] = 0  dist[1] = 24.866069     path[1] = 7
Visited[2] = 0  dist[2] = 25.142136     path[2] = 12
Visited[3] = 1  dist[3] = 63.866069     path[3] = 17
Visited[4] = 1  dist[4] = 500000.000000 path[4] = -1
Visited[5] = 1  dist[5] = 50.322476     path[5] = 16
Visited[6] = 1  dist[6] = 39.142136     path[6] = 14
Visited[7] = 0  dist[7] = 10.000000     path[7] = 0
Visited[8] = 0  dist[8] = 40.866069     path[8] = 11
Visited[9] = 1  dist[9] = 500000.000000 path[9] = -1
Visited[10] = 1 dist[10] = 50.300050    path[10] = 8
Visited[11] = 0 dist[11] = 25.866069    path[11] = 12
Visited[12] = 0 dist[12] = 11.000000    path[12] = 0
Visited[13] = 0 dist[13] = 40.142136    path[13] = 2
Visited[14] = 0 dist[14] = 29.142136    path[14] = 15
Visited[15] = 0 dist[15] = 14.142136    path[15] = 0
Visited[16] = 1 dist[16] = 39.142136    path[16] = 2
Visited[17] = 1 dist[17] = 53.866069    path[17] = 8

2024,10.26更新了一下,发现我的Dijkstra算法用错了,这是以前的,哈哈,我这样就无法保持根了,但是我发现依旧无妨解决问题时,更加难受了。

void Dijkstra(LGraph M, double *dist, int *path)
{MinHeap H;struct HeapNode HNode;bool *collected;PtrToAdjVNode G;H = Init_dist(M);collected = (bool*)malloc(sizeof(bool) * (M ->N + 1));Init_DP(dist, path, M ->N);for(int i = 0; i <= M ->N; i++){Creat_Heap(i, M, H, collected);collected[i] = true;while(HNode = Delete_Heap(H), HNode.sign != -1){collected[HNode.sign] = true;if(dist[HNode.sign] > HNode.dist){dist[HNode.sign] = HNode.dist;path[HNode.sign] = i;}for(G = M ->G[HNode.sign] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V] && dist[G ->V] > dist[HNode.sign] + G ->dist){dist[G ->V] = dist[HNode.sign] +  G ->dist;path[G ->V] = HNode.sign;}}}	}
}

如我在这里的判定,感觉够可以了吧,先考虑最小跳跃,其次最短距离,最后最小跳。tmd我是真服了!

int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path)
{int N, Node;int Cycle;int MinCycle = (int)INFITY;double dmin = INFITY;double MinJump;int MinSkip;for(int i = 1; i <= M ->N; i++){Cycle = 0;if(Visited[i] && Find_Root(path, i)){N = i;while(N != 0){if(path[N] == 0){MinSkip = N;}N = path[N];Cycle++;}if(Cycle == MinCycle){if(dist[i] < dmin){Node = i;}if(dist[i] == dmin){if(dist[MinSkip] < MinJump){Node = i;}}}if(Cycle < MinCycle){dmin = dist[i];MinJump = dist[MinSkip];MinCycle = Cycle;Node = i;	}}}return Node;
}

 之前的错误代码留个纪念

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<math.h>const double INFITY = 500000.0;typedef struct Coordinate *Point;
struct Coordinate{int X;int Y;
};typedef struct ENode *PtrToENode;
typedef PtrToENode Edge;
struct ENode{int V1, V2;double dist;	
};typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{int V;double dist;PtrToAdjVNode Next;	
};typedef struct VNode **AdjList;
struct VNode{PtrToAdjVNode FirstEdge;	
};typedef struct GNode *LGraph;
struct GNode{int N;double D;AdjList G;
};typedef struct HeapNode *HN;
struct HeapNode{int sign;double dist;
};typedef struct Heap *MinHeap;
struct Heap{HN data;int Size;
};typedef struct Node *Stack;
struct Node{int data;Stack Next;
};LGraph Build_Graph(LGraph M, Point *Array, bool *Visited);
LGraph Init_Graph();
Point* Read_Point_Array(int N);
bool Up_ashore(Point P, double D);
double Dict_E(Point start, Point end, double D);
void Insert_Graph(LGraph M, Edge E);
MinHeap Init_dist(LGraph M);
void Insert_Heap(MinHeap H, double Data, int sign);
struct HeapNode Delete_Heap(MinHeap H);
void Creat_Heap(int head, LGraph M, MinHeap H, bool *collected);
void Init_DP(double *dist, int *path, int N);
void Dijkstra(LGraph M, double *dist, int *path);
bool Find_Root(int *path, int N);
int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path);
Stack Init_Stack();
void Push_Stack(Stack S, int data);
int Pop_Stack(Stack S);
bool IsEmpty(Stack S);
void Push_path_data(Stack S,  int *path, int Node);
void Print_Path(Stack S, Point *Array);int main()
{LGraph M;Point *Array;bool *Visited;M = Init_Graph();Array = Read_Point_Array(M ->N);Visited = (bool*)calloc(M ->N + 1, sizeof(bool));M = Build_Graph(M, Array, Visited);if(M){double *dist;int *path;int Node;Stack S;dist = (double*)malloc(sizeof(double) * (M ->N + 1));path = (int*)malloc(sizeof(int) * (M ->N + 1));Dijkstra(M, dist, path);Node = Fllush_Mindata(M, Visited, dist, path);S = Init_Stack();Push_path_data(S, path, Node);Print_Path(S, Array);}	return 0;
}
void Print_Path(Stack S, Point *Array)
{int Node;printf("%d\n", S ->data);while(!IsEmpty(S)){Node = Pop_Stack(S);printf("%d %d\n", Array[Node] ->X, Array[Node] ->Y);}
}
void Push_path_data(Stack S,  int *path, int Node)
{if(Node == 0){return ;}if(Node != 0){Push_Stack(S, Node);S ->data++;}Push_path_data(S, path, path[Node]);
}
int Fllush_Mindata(LGraph M, bool *Visited, double *dist, int *path)
{int N, Node;int Cycle;int MinCycle = (int)INFITY;double dmin = INFITY;for(int i = 1; i <= M ->N; i++){Cycle = 0;if(Visited[i] && Find_Root(path, i)){N = path[i];while(N != 0){dist[i] += dist[N];N = path[N];Cycle++;}if(Cycle == MinCycle){if(dist[i] < dmin){Node = i;}}if(Cycle < MinCycle){dmin = dist[i];MinCycle = Cycle;Node = i;	}}}return Node;
}
bool Find_Root(int *path, int N)
{if(N == 0){return true;}if(N == -1){return  false;}return Find_Root(path, path[N]);
}
LGraph Build_Graph(LGraph M, Point *Array, bool *Visited)
{Edge E;bool Up = false;bool Up_D = false;E = (Edge)malloc(sizeof(struct ENode));if(Up_ashore(Array[0], M ->D + 7.5)){printf("1\n");return NULL;}for(int i = 1; i <= M ->N; i++){if(Up_ashore(Array[i], M ->D + 7.5)){Visited[i] = true;Up = true;}E ->dist = Dict_E(Array[0], Array[i], M ->D + 7.5);E ->V1 = 0;E ->V2 = i;if(E ->dist != 0 && E ->dist > 7.5){Up_D = true;Insert_Graph(M, E);}}if(!Up || !Up_D){printf("0\n");return NULL;}for(int i = 1; i <= M ->N; i++){for(int j = i + 1; j <= M ->N; j++){E ->dist = Dict_E(Array[i], Array[j], M ->D);E ->V1 = i;E ->V2 = j;if(E ->dist != 0){Insert_Graph(M, E);}}	}return M;
}
void Dijkstra(LGraph M, double *dist, int *path)
{MinHeap H;struct HeapNode HNode;bool *collected;PtrToAdjVNode G;H = Init_dist(M);collected = (bool*)malloc(sizeof(bool) * (M ->N + 1));Init_DP(dist, path, M ->N);for(int i = 0; i <= M ->N; i++){Creat_Heap(i, M, H, collected);collected[i] = true;while(HNode = Delete_Heap(H), HNode.sign != -1){collected[HNode.sign] = true;if(dist[HNode.sign] > HNode.dist){dist[HNode.sign] = HNode.dist;path[HNode.sign] = i;}for(G = M ->G[HNode.sign] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V] && dist[G ->V] > dist[HNode.sign] + G ->dist){dist[G ->V] = dist[HNode.sign] +  G ->dist;path[G ->V] = HNode.sign;}}}	}
}void Init_DP(double *dist, int *path, int N)
{for(int i = 0; i <= N; i++){dist[i] = INFITY;path[i] = -1;}
}
void Creat_Heap(int head, LGraph M, MinHeap H, bool *collected)
{PtrToAdjVNode G;for(G = M ->G[head] ->FirstEdge; G; G = G ->Next){if(!collected[G ->V]){Insert_Heap(H, G ->dist, G ->V);}}
}void Insert_Graph(LGraph M, Edge E)
{PtrToAdjVNode NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V2;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V1] ->FirstEdge;M ->G[E ->V1] ->FirstEdge = NewNode;NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));NewNode ->V = E ->V1;NewNode ->dist = E ->dist;NewNode ->Next = M ->G[E ->V2] ->FirstEdge;M ->G[E ->V2] ->FirstEdge = NewNode;
}LGraph Init_Graph()
{LGraph M;M = (LGraph)malloc(sizeof(struct GNode));scanf("%d %lf", &M ->N, &M ->D);M ->G = (AdjList)malloc(sizeof(struct VNode) * (M ->N + 1));for(int i = 0; i <= M ->N; i++){M ->G[i] = (struct VNode*)malloc(sizeof(struct VNode));M ->G[i] ->FirstEdge = NULL;}return M;
}
Point* Read_Point_Array(int N)
{Point *Array;Array = (Point*)malloc(sizeof(Point) * (N + 1));Array[0] = (Point)malloc(sizeof(struct Coordinate));Array[0] ->X = 0;Array[0] ->Y = 0;for(int i = 1; i <= N; i++){Array[i] = (Point)malloc(sizeof(struct Coordinate));scanf("%d %d", &(Array[i] ->X), &(Array[i] ->Y));}return Array;
}
double Dict_E(Point start, Point end, double D)
{double dis;dis = sqrt(pow(start ->X - end ->X, 2) + pow(start ->Y - end ->Y, 2));if(dis <= D){return dis;}else{return 0;}
}
bool Up_ashore(Point P, double D)
{return (abs(P ->X) >= 50 - D || abs(P ->Y) >= 50 - D);
}MinHeap Init_dist(LGraph M)
{MinHeap dist;dist = (MinHeap)malloc(sizeof(struct Heap) * (M ->N + 1));dist->data = (HN)malloc(sizeof(struct HeapNode) * (M ->N + 1));dist ->Size = 0;dist ->data[0].sign = -1;dist ->data[0].dist = -1;return dist;
}
void Insert_Heap(MinHeap H, double Data, int sign)
{int i;i = ++(H ->Size);for(; Data < H ->data[i/2].dist; i /= 2){H ->data[i].dist = H ->data[i/2].dist;H ->data[i].sign = H ->data[i/2].sign;}H ->data[i].dist = Data;H ->data[i].sign = sign;
}
struct HeapNode Delete_Heap(MinHeap H)
{int Child, Parent;struct HeapNode Min, Temp;if(H ->Size == 0){return H ->data[0];}Min = H ->data[1];Temp = H ->data[H ->Size --];for(Parent = 1; Parent * 2 <= H ->Size; Parent = Child){Child = Parent * 2;if((Child != H ->Size) && H ->data[Child].dist > H ->data[Child + 1].dist){Child++;}if(Temp.dist <= H ->data[Child].dist){break;}else{H ->data[Parent].dist = H ->data[Child].dist;H ->data[Parent].sign = H ->data[Child].sign;}	}H ->data[Parent].dist = Temp.dist;H ->data[Parent].sign = Temp.sign;return Min;
}Stack Init_Stack()
{Stack S;S = (Stack)malloc(sizeof(struct Node));S ->data = 1;S ->Next = NULL;return S;
}
void Push_Stack(Stack S, int data)
{Stack T;T = (Stack)malloc(sizeof(struct Node));T ->data = data;T ->Next = S ->Next;S ->Next = T;
}
int Pop_Stack(Stack S)
{int temp;Stack Top;if(IsEmpty(S)){printf("IS Empty the Stack!\n");return -1;}else{Top = S ->Next;S ->Next = Top ->Next;temp = Top ->data;free(Top);return temp;}
}
bool IsEmpty(Stack S)
{return (S->Next == NULL);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/412710.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SQL】餐馆营业额七日均线数据

目录 题目 分析 代码 题目 表: Customer ------------------------ | Column Name | Type | ------------------------ | customer_id | int | | name | varchar | | visited_on | date | | amount | int | -----------------------…

Docker 数据卷管理及优化

目录 1 数据卷实现的目的 2 为什么要用数据卷 3 docker的两种数据卷 3.1 bind mount 数据卷 实践实例&#xff1a; 3.2 docker managed 数据卷 实验实例&#xff1a; 3.3 bind mount 数据卷和docker managed 数据卷的对比 3.3.1 相同点&#xff1a; 3.3.2 不同点&#xff1a; …

【网络安全】服务基础第一阶段——第二节:Windows系统管理基础----虚拟化IP地址以及用户与组管理

目录 一、Windows网络测试工具 1.1.ping命令 1.2.tracert命令 二、IP实验内容 2.1 实验一 2.2 实验二 三、用户与组管理 3.1 用户与账户概述 3.2 用户管理 3.3 用户增删改查 3.4 增加用户 3.5 修改用户属性 3.6 删除用户 3.7 组账户概述 3.8 组账户增删改查 四、…

没有编程基础?这款数据分析工具也能轻松上手

在当前快节奏的工业环境中&#xff0c;工厂管理者越来越依赖数据分析来优化生产流程、提升效率、降低成本。然而&#xff0c;很多传统的数据分析工具不仅操作复杂&#xff0c;而且费用高昂&#xff0c;让不少工厂望而却步。最近&#xff0c;我发现了一款非常实用的报表工具&…

安卓主板_MTK安卓主板定制_联发科主板/开发板方案

这款安卓主板采用了联发科的MTK8788、MTK8768及MTK8766系列芯片平台&#xff0c;运用了64位四核/八核 Cortex-A53/A73架构&#xff0c;主频高达2.0 GHz。主板配置了4GB LPDDR3内存和64GB eMMC存储&#xff0c;同时配备了ARM Mail-T450 MP2图形处理单元(GPU)&#xff0c;使其在4…

Java性能优化传奇之旅--Java万亿级性能优化之电商平台高峰时段性能大作战:策略与趋势洞察

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

【Linux】共享内存

目录 原理 代码 在之前&#xff0c;无论是匿名管道还是命名管道&#xff0c;说到底都是基于文件的通信&#xff0c;也就意味着没有为了通信让OS单独设计一套通信模块代码&#xff0c;而是直接复用内核中文件相关的数据结构、缓冲区、代码来实现通信的&#xff0c;这在一定程度…

ET6框架(七)Excel配置工具

文章目录 一、Excel表的基本规则&#xff1a;二、特殊特殊标记三、编译路径说明四、动态获取数据五、可导表类型查看: 一、Excel表的基本规则&#xff1a; 在框架中我们的Excel配置表在ET > Excel文件夹中 1.在表结构中需要注意的是起始点必须在第三行第三列&#xff0c;且…

鸿蒙开发 数组改变,ui渲染没有刷新

问题描述&#xff1a; 数组push, 数组长度改变&#xff0c;ui也没有刷新 打印出了数组 console.log(this.toDoData.map(item > ${item.name}).join(, ), this.toDoData.length) 原代码&#xff1a; Text().fontSize(36).margin({ right: 40 }).onClick(() > {TextPicker…

mysql学习教程,从入门到精通,MySQL介绍(1)

1、MySQL 教程 本教程是为初学者准备的&#xff0c;以帮助他们理解与MySQL语言相关的基础知识和高级概念。 mysql MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系…

如何使用IDEA远程访问家里或者公司中无公网IP的内网MySQL数据库

文章目录 前言1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql5. 固定连接公网地址6. 固定地址连接测试 前言 本教程主要介绍如何使用Cpolar内网穿透工具实现在IDEA中也可以远程访问家里或者公司的数据库&#xff0c;提高开发效率&#xff01;无…

Monibuca实战:如何用Go语言打造高效的直播后端

简介 Monibuca&#xff08;简称&#xff1a;m7s&#xff09; 是一个开源的实时流媒体服务器开发框架&#xff0c;使用 Go 语言编写。 它的设计目标是提供一个高性能、可扩展、易于定制的实时流媒体服务器解决方案。 Monibuca 的核心理念是模块化&#xff0c;允许开发者根据需…

linux服务器/虚拟机安装redis

py3安装&#xff08;慢的一批无语了&#xff09; wget http://cdn.npm.taobao.org/dist/python/3.6.5/Python-3.6.5.tgz && tar -zxvf Python-3.6.5.tgz && cd Python-3.6.5/ && ./configure --prefix/usr/local/python3 --with-ssl && make …

Golang | Leetcode Golang题解之第373题查找和最小的K对数字

题目&#xff1a; 题解&#xff1a; func kSmallestPairs(nums1, nums2 []int, k int) (ans [][]int) {m, n : len(nums1), len(nums2)// 二分查找第 k 小的数对和left, right : nums1[0]nums2[0], nums1[m-1]nums2[n-1]1pairSum : left sort.Search(right-left, func(sum in…

ESP32-IDF http请求崩溃问题分析与解决

文章目录 esp32s3 http请求崩溃问题代码讨论修正后不崩溃的代码esp32相关文章 ESP32S3板子, 一运行http请求百度网站的例子, 就会panic死机, 记录下出现及解决过程. esp32s3 http请求崩溃 一执行http请求的perform就会崩溃, 打印如图 ESP32-IDF 的http请求代码是根据官方dem…

Qt:玩转QPainter序列六(图形)

前言 继续看源码。 正文 剩下的大部分都是画各种图形的函数&#xff0c;它们一般都有多个重载版本&#xff0c;我就不一 一介绍使用了&#xff0c;只挑其中的一部分使用一下。 在 QPainter 类中&#xff0c;这些方法涉及到绘图的各种功能&#xff0c;主要用于设置视图变换、…

kube-scheduler调度任务的执行过程分析与源码解读(二)

概述 摘要&#xff1a; 上文我们对Kube-scheduler的启动流程进行了分析&#xff0c;本文继续探究kube-scheduler执行pod的调度任务的过程。 正文 说明&#xff1a;基于 kubernetes v1.12.0 源码分析 上文讲到kube-scheduler组件通过sched.Run() 启动调度器实例。在sched.Run(…

校园牛奶订购配送小程序开发制作方案

校园牛奶订购配送小程序系统的开发方案&#xff0c;包括对用户需求的分析、目标用户的界定、使用场景的设定以及开发功能模块的规划。校园牛奶订购配送小程序系统主要是为校园内学生和教职工提供牛奶订购与配送服务。 目标用户 主要面向在校学生、教职工以及其他有牛奶订购需求…

这四种人不能合作做生意

合伙创业千万不要和这四种人合伙&#xff0c;不然公司做大了都不是你的&#xff01; 一、不愿出钱的人&#xff0c;不愿出钱就不会有决心。公司一旦有风吹草动&#xff0c;最先跑路的都是没有出钱的。 二、不愿付出时间的人&#xff0c;想用业余时间参与&#xff0c;不愿全身心…

如何使用Svg矢量图封装引用到vue3项目中

前言 在现代前端开发中&#xff0c;SVG&#xff08;可缩放矢量图形&#xff09;因其高质量和灵活性成为了图标和图形设计的热门选择。对于 Vue 3 项目而言&#xff0c;将 SVG 图标封装和引用到项目中不仅能提升性能&#xff0c;还能带来更高的可维护性和一致性。SVG 图标本质上…