DSOJ I Love PKU(我爱北大)

来源:互联网 发布:dnf战斗力基础属性算法 编辑:程序博客网 时间:2024/05/17 22:03

题目链接

#include<stdio.h>//I love PKU#include<string.h>#include<stdlib.h>#define INFINITE 9999999#define MaxVexnum 30//顶点的最大个数#define MaxArcnum 50//边的最大个数typedef struct graph{int vexnum, arcnum;char *vexname[MaxVexnum];int Matrix[MaxVexnum][MaxVexnum];}Graph;void getvex(Graph *G){int i, Vexnum;char temp[21];scanf("%d", &Vexnum);G->vexnum = Vexnum;for (i = 0; i < G->vexnum; i++){G->vexname[i] = (char *)malloc(sizeof(char));scanf("%s", G->vexname[i]);}}int locatevex(Graph *G, char *name){int i;for (i = 0; i < G->vexnum; i++){if (strcmp(G->vexname[i], name) == 0)return i;}exit(0);}void create_graph(Graph *G){int i, j, k, weight, Arcnum;char s1[21], s2[21];getvex(G);for (i = 0; i < G->vexnum; i++)for (j = 0; j < G->vexnum; j++){if (i == j) G->Matrix[i][j] = 0;else G->Matrix[i][j] = INFINITE;}scanf("%d", &Arcnum);G->arcnum = Arcnum;for (k = 0; k < G->arcnum; k++){scanf("%s", s1);scanf("%s", s2);scanf("%d", &weight);i = locatevex(G, s1);j = locatevex(G, s2);if (weight<G->Matrix[i][j])//处理一些特殊的数据,同一条边多次出现,权值取最小的G->Matrix[i][j] = G->Matrix[j][i] = weight;//无向图}}void floyd(Graph *G, int path[][MaxVexnum], int dis[][MaxVexnum])//弗洛伊德算法所有两两顶点最短路径{int i, j, k;for (i = 0; i<G->vexnum; i++)for (j = 0; j<G->vexnum; j++){dis[i][j] = G->Matrix[i][j];if (dis[i][j]<INFINITE)path[i][j] = i;//表示从i到j必须经过ielsepath[i][j] = -1;}for (k = 0; k<G->vexnum; k++)//k表示第k次试探,求得的是从vi到vj中间顶点的序号不大于k的路径for (i = 0; i<G->vexnum; i++)for (j = 0; j<G->vexnum; j++){if (dis[i][j]>(dis[i][k] + dis[k][j])){dis[i][j] = dis[i][k] + dis[k][j];path[i][j] = path[k][j];//path[i][j]=path[j][k]可以保证此时的path[i][j]即为从i到j所必须经过的点,//并且该点是距离j最近的点,在恢复路径时只需不断向前找直到到达顶点i即可,//而如果用path[i][j]=k可能遗失掉(k,j)之间的点,即此时的k不一定是距离i//最近的点,不利用恢复路径}}}void print_dis(Graph *G, int path[][MaxVexnum], int dis[][MaxVexnum], char *start, char *end){int i, j, k, t;i = locatevex(G, start);j = locatevex(G, end);if (i == j){printf("%s\n", end);return;}printf("%s", G->vexname[i]);k = path[j][i];//由于path中为i到j的逆路径,因此输出时输出从j到i的路径t = i;//t为路径中k的后继while (k != j){printf("->(%d)->", G->Matrix[k][t]);printf("%s", G->vexname[k]);t = k;k = path[j][k];}printf("->(%d)->", G->Matrix[t][k]);printf("%s\n", G->vexname[j]);}int main(){Graph G;int dis[MaxVexnum][MaxVexnum], path[MaxVexnum][MaxVexnum];char start[21], end[21];int N, i;create_graph(&G);floyd(&G, path, dis);scanf("%d", &N);while (N--){scanf("%s", start);scanf("%s", end);print_dis(&G, path, dis, start, end);}return 0;}


0 0
原创粉丝点击