You are assigned to design network
connections between certain points in a wide area. You are given a set of
points in the area, and a set of possible routes for the cables that may
connect pairs of points. For each possible route between two points, you are
given the length of the cable that is needed to connect the points over that
route. Note that there may exist many possible routes between two given points.
It is assumed that the given possible routes connect (directly or indirectly) each
two points in the area.
Your task is to design the network
for the area, so that there is a connection (direct or indirect) between every
two points (i.e., all the points are interconnected, but not necessarily by a
direct cable), and that the total length of the used cable is minimal.
Input. The input
file consists of a number of data sets. Each data set defines one required
network. The first line of the set contains two integers: the first defines the
number P of the given points, and the second the number R of given routes
between the points. The following R lines define the given routes between the
points, each giving three integer numbers: the first two numbers identify the
points, and the third gives the length of the route. The numbers are separated
with white spaces. A data set giving only one number P = 0 denotes the end of
the input. The data sets are separated with an empty line.
The
maximal number of points is 50. The maximal length of a given route is 100. The
number of possible routes is unlimited. The nodes are identified with integers
between 1 and P (inclusive). The routes between two points i and j may be given as i j or as j i.
Output. For each
data set, print one number on a separate line that gives the total length of
the cable used for the entire designed network.
Sample input |
Sample output |
1 0 2 3 1 2 37 2 1 17 1 2 68 3 7 1 2 19 2 3 11 3 1 7 1 3 5 2 3 89 3 1 91 1 2 32 5 7 1 2 5 2 3 7 2 4 8 4 5 11 3 5 10 1 5 6 4 2 12 0 |
0 17 16 26 |
графы – минимальное остовное
дерево – алгоритм Прима
Из-за
мультиребер алгоритм Крускала дает Time Limit. Граф содержит не более 50
вершин. Построим матрицу расстояний m, где m[i][j] = m[j][i]
хранит длину кратчайшего ребра между i
и j. Запустим алгоритм Прима и найдем
длину минимального остова.
Реализация алгоритма
#include <stdio.h>
#include <math.h>
#include <string.h>
#define MAX 60
int m[MAX][MAX];
int i, j, v, dist, to, p, q, a, b, c;
int used[MAX], min_e[MAX], end_e[MAX];
int main(void)
{
while(scanf("%d
%d",&p,&q), p)
{
memset(m,0x3F,sizeof(m));
for(i = 0; i < q; i++)
{
scanf("%d %d %d",&a,&b,&c);
if (c < m[a][b])
{
m[a][b] =
m[b][a] = c;
}
}
memset(min_e,0x3F,sizeof(min_e));
memset(end_e,-1,sizeof(end_e));
memset(used,0,sizeof(used));
dist = 0; min_e[1]
= 0;
for (i = 0; i < p; i++)
{
v = -1;
for (j = 1; j <= p; j++)
if (!used[j] && (v == -1 || min_e[j] <
min_e[v])) v = j;
used[v] = 1;
if (end_e[v] != -1) dist += m[end_e[v]][v];
for (to = 1; to <= p; to++)
{
int dV_TO = m[v][to];
if (!used[to] && (dV_TO < min_e[to]))
{
min_e[to] =
dV_TO;
end_e[to] =
v;
}
}
}
printf("%d\n",dist);
}
return 0;
}