07-图4 哈利·波特的考试(25 分)多源最短路,邻接矩阵
哈利·波特要考试了,他需要你的帮助。这门课学的是用魔咒将一种动物变成另一种动物的本事。例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等。反方向变化的魔咒就是简单地将原来的魔咒倒过来念,例如ahah可以将老鼠变成猫。另外,如果想把猫变成鱼,可以通过念一个直接魔咒lalala,也可以将猫变老鼠、老鼠变鱼的魔咒连起来念:hahahehe。
现在哈利·波特的手里有一本教材,里面列出了所有的变形魔咒和能变的动物。老师允许他自己带一只动物去考场,要考察他把这只动物变成任意一只指定动物的本事。于是他来问你:带什么动物去可以让最难变的那种动物(即该动物变为哈利·波特自己带去的动物所需要的魔咒最长)需要的魔咒最短?例如:如果只有猫、鼠、鱼,则显然哈利·波特应该带鼠去,因为鼠变成另外两种动物都只需要念4个字符;而如果带猫去,则至少需要念6个字符才能把猫变成鱼;同理,带鱼去也不是最好的选择。
输入格式:
输入说明:输入第1行给出两个正整数N (≤100)和M,其中N是考试涉及的动物总数,M是用于直接变形的魔咒条数。为简单起见,我们将动物按1~N编号。随后M行,每行给出了3个正整数,分别是两种动物的编号、以及它们之间变形需要的魔咒的长度(≤100),数字之间用空格分隔。
输出格式:
输出哈利·波特应该带去考场的动物的编号、以及最长的变形魔咒的长度,中间以空格分隔。如果只带1只动物是不可能完成所有变形要求的,则输出0。如果有若干只动物都可以备选,则输出编号最小的那只。
输入样例:
6 11
3 4 70
1 2 1
5 4 50
2 6 50
5 6 60
1 3 70
4 6 60
3 6 80
5 1 100
2 4 60
5 2 80
输出样例:
4 70
我的答案
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 #define TRUE 1 6 #define FALSE 0 7 8 #define MaxVertexNum 100 9 #define INFINITY 65535 10 typedef int Vertex; 11 typedef int WeightType; 12 // typedef char DataType; 13 14 //边 15 typedef struct ENode *PtrToENode; 16 struct ENode { 17 Vertex V1, V2; 18 WeightType Weight; 19 }; 20 typedef PtrToENode Edge; 21 22 //图结点 23 typedef struct GNode *PtrToGNode; 24 struct GNode { 25 int Nv; 26 int Ne; 27 WeightType G[MaxVertexNum][MaxVertexNum]; 28 // DataType Data[MaxVertexNum]; 29 }; 30 typedef PtrToGNode MGraph; 31 32 MGraph CreateGraph(int VertexNum) 33 { 34 Vertex V, W; 35 MGraph Graph; 36 37 Graph = (MGraph)malloc(sizeof(struct GNode)); 38 Graph->Nv = VertexNum; 39 Graph->Ne = 0; 40 41 for(V=0;V<Graph->Nv;V++) 42 for(W=0;W<Graph->Nv;W++) 43 Graph->G[V][W] = INFINITY; 44 45 return Graph; 46 } 47 48 void InsertEdge(MGraph Graph, Edge E) 49 { 50 Graph->G[E->V1][E->V2] = E->Weight; 51 Graph->G[E->V2][E->V1] = E->Weight; 52 } 53 54 MGraph BuildGraph() 55 { 56 MGraph Graph; 57 Edge E; 58 // Vertex V; 59 int Nv, i; 60 61 scanf("%d", &Nv); 62 Graph = CreateGraph(Nv); 63 64 scanf("%d\n", &(Graph->Ne)); 65 if(Graph->Ne != 0) { 66 E = (Edge)malloc(sizeof(struct ENode)); 67 for(i=0;i<Graph->Ne;i++) { 68 scanf("%d %d %d\n", &E->V1, &E->V2, &E->Weight); 69 E->V1--; 70 E->V2--; 71 InsertEdge(Graph, E); 72 } 73 } 74 75 // for(V=0;V<Graph->Nv;V++) 76 // scanf(" %c", &(Graph->Data[V])); 77 78 return Graph; 79 } 80 81 int Floyd(MGraph Graph, WeightType D[][MaxVertexNum]) 82 { 83 Vertex i, j, k; 84 85 for(i=0;i<Graph->Nv;i++) 86 for(j=0;j<Graph->Nv;j++) { 87 D[i][j] = Graph->G[i][j]; 88 // path[i][j] = -1; 89 } 90 91 for(k=0;k<Graph->Nv;k++) { 92 for(i=0;i<Graph->Nv;i++) { 93 for(j=0;j<Graph->Nv;j++) { 94 if(D[i][k]+D[k][j] < D[i][j]) { 95 D[i][j] = D[i][k] + D[k][j]; 96 if(i==j && D[i][j] < 0) 97 return FALSE; 98 // path[i][j] = k; 99 } 100 } 101 } 102 } 103 return TRUE; 104 } 105 106 void PrintGraph(MGraph Graph) 107 { 108 Vertex V, W; 109 printf("Graph:\n"); 110 for(V=0;V<Graph->Nv;V++) { 111 for(W=0;W<Graph->Nv;W++) 112 printf("%5d " ,Graph->G[V][W]); 113 printf("\n"); 114 } 115 printf("-----------------------\n"); 116 } 117 118 WeightType FindMaxDist(WeightType D[][MaxVertexNum], Vertex i, int N) 119 { 120 WeightType MaxDist; 121 Vertex j; 122 123 MaxDist = 0; 124 for(j=0;j<N;j++) 125 if(i!=j && D[i][j]>MaxDist) 126 MaxDist = D[i][j]; 127 128 return MaxDist; 129 } 130 131 void FindAnimal(MGraph Graph) 132 { 133 WeightType D[MaxVertexNum][MaxVertexNum], MaxDist, MinDist; 134 Vertex Animal, i; 135 136 Floyd(Graph, D); 137 // for(i=0;i<10;i++) { 138 // for(Animal=0;Animal<10;Animal++) 139 // printf("%6d", D[i][Animal]); 140 // printf("\n"); 141 // } 142 MinDist = INFINITY; 143 for(i=0;i<Graph->Nv;i++) { 144 MaxDist = FindMaxDist(D, i, Graph->Nv); 145 if(MaxDist == INFINITY) { 146 printf("0\n"); 147 return; 148 } 149 if(MinDist > MaxDist) { 150 MinDist = MaxDist; 151 Animal = i + 1; 152 } 153 } 154 printf("%d %d\n", Animal, MinDist); 155 } 156 157 int main() 158 { 159 MGraph Graph; 160 Graph = BuildGraph(); 161 // PrintGraph(Graph); 162 163 FindAnimal(Graph); 164 return 0; 165 }
无欲速,无见小利。欲速,则不达;见小利,则大事不成。