题意:给定点、P条边、P条边的长度、终点、若干起点,求这若干起点到终点最短路径的最小值。(注意:两个点之间可能有多条边)
解题思路:
- 读入输入,处理可以得到一张表table[i][j] = k,代表i点到j点有一条长为k的边(因为两个点之间可能有多条边,所以在处理过程中只保存较小的边)。并且可以得到起点和终点
- 以终点为source进行Dijkstra,可以得到distance[i] = j,代表从source到节点i的最短路径。
- 遍历distance[i] = j,找到其中i为起点情况下最小的j,那么就得到了最终的结果
代码:
/*
ID: zc.rene1
LANG: C
PROG: comehome
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 20000000
int P;
int table[52][52];
int visited[52];
int cows_in[52];
void GetInput(FILE *fin)
{
int i, j, distance;
char c[2];
int b[2];
for (i=0; i<52; i++)
{
for (j=0; j<52; j++)
{
table[i][j] = MAX;
}
}
for (i=0; i<52; i++)
{
cows_in[i] = 0;
visited[i] = 1;
}
fscanf(fin, "%d\n", &P);
for (i=0; i<P; i++)
{
fscanf(fin, "%c %c %d\n", &c[0], &c[1], &distance);
for (j=0; j<2; j++)
{
if (c[j] <= 'Z')
{
b[j] = c[j] - 'A';
if (c[j] != 'Z')
{
cows_in[b[j]] = 1;
}
}
else
{
b[j] = c[j] - 'a' + 26;
}
visited[b[j]] = 0;
}
if (distance < table[b[0]][b[1]])
{
table[b[0]][b[1]] = distance;
table[b[1]][b[0]] = distance;
}
}
}
int FirstLeastUnvisted(int *distance)
{
int i, ret = 52, min = MAX;
for (i=0; i<52; i++)
{
if (!visited[i])
{
if (distance[i] < min)
{
min = distance[i];
ret = i;
}
}
}
return ret;
}
void Dijkstra(int source, FILE *fout)
{
int distance[52];
int i, j, min_i, min = MAX;
for (i=0; i<52; i++)
{
distance[i] = MAX;
}
distance[source] = 0;
while ((i = FirstLeastUnvisted(distance)) != 52)
{
visited[i] = 1;
for (j=0; j<52; j++)
{
if (table[i][j] != MAX)
{
if ((distance[i] + table[i][j]) < distance[j])
{
distance[j] = distance[i] + table[i][j];
}
}
}
}
for (i=0; i<52; i++)
{
if (cows_in[i] == 1)
{
if (distance[i] < min)
{
min = distance[i];
min_i = i;
}
}
}
fprintf(fout, "%c %d\n", min_i + 'A', min);
}
int main(void)
{
FILE *fin, *fout;
fin = fopen("comehome.in", "r");
fout = fopen("comehome.out", "w");
/*get input*/
GetInput(fin);
/*Dijkstra*/
Dijkstra(25, fout);
return 0;
}