
- •Олимпиадные задачи и решения
- •Векторы (100 баллов)
- •Погодные условия (100 баллов)
- •Шоколадные плитки (100 баллов)
- •Работники (100 баллов)
- •Робот (100 баллов)
- •Зал Круглых Столов (100 баллов)
- •Вто (100 баллов)
- •Вишня (100 баллов)
- •Алхимия (100 баллов)
- •Цепь (100 баллов)
- •Казино (100 баллов)
- •Система уравнений (100 баллов)
- •Забавный конфуз
- •Соревнование
- •Абракадабра
- •Циферблат
- •Многоугольники
- •Квадрат
- •Лабиринт
- •Задача “Шифр”
- •Задача “Школы”
- •Последовательность
- •Автобус
- •Головоломка
- •Электронная почта
- •Виртуляндия
- •Конвейер
- •Новости
Задача “Школы”
С целью подготовки к проведению олимпиады по информатике мэр решил обеспечить надежным электроснабжением все школы города. Для этого необходимо провести линию электропередач от альтернативного источника электроэнергии “Майбуття” к одной из школ города (к какой неважно), а также соединить линиямии электропередач некоторые школы между собой.
Считается, что школа имеет надежное электроснабжение, если она напрямую связана с источником “Майбуття”, либо с одной из тех школ, которые имеют надежное электроснабжение.
Известна стоимость соединения между некоторыми парами школ. Мэр города решил выбрать одну из двух наиболее экономичных схем электроснабжения (стоимость схемы равняется сумме стоимостей соединений пар школ).
Задание
Напишите программу SCHOOLS, которая вычисляет стоимость двух наиболее экономных схем альтернативного электроснабжения школ.
Входные данные
В первой строке входного файла SCHOOLS.DAT находятся два натуральных числа, разделенных пробелом: N (3 N 100), количество школ в городе, и M – количество возможных соединений между ними. В каждой из последующих M строк находятся по три числа: Ai, Bi, Ci, разделенных пробелами, где Ci – стоимость прокладки линии электроснабжения (1 Ci 300) от школы Ai до школы Bi (i=1,2,…,N).
Пример входного файла
5 8
1 3 75
3 4 51
2 4 19
3 2 95
2 5 42
5 4 31
1 2 9
3 5 66
Выходные данные
В единственной строке выходного файла SCHOOLS.SOL должны содержаться два натуральных числа S1 и S2, разделенных пробелом – две наименьшие стоимости схем (S1S2). S1=S2 тогда и только тогда, когда существует несколько схем надежного электроснабжения наименьшей стоимости.
Пример выходного файла
110 121
{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q+,R+,S+,T-,V+,X+}
{$M 16384,0,655360}
const
MaxN = 100;
FileIn = 'schools.dat';
FileOut = 'schools.sol';
type
PList = ^TList;
TList = record
Ver, Leng : integer;
Next : PList;
end;
var
A : array [1..MaxN, 1..MaxN] of integer;
{ Adjacency matrix for graph}
Dist : array [1..MaxN,1..2] of integer;
BestTree : array [1..MaxN] of PList;
{ Each element of array cotains a reference to list of the verteses
that are reachable from the vertex with number equal to the index
of element
}
Dynamic : array [1..MaxN, 1..MaxN] of integer;
{ Array contains matrix of maximal edge's length at first spannig tree}
{List : array [1..(MaxN*(MaxN-1) div 2), 1..3] of integer;}
{ Array contains the list of edges
1 - first vertex of edge
2 - second vertex of edge
3 - length of current edge
4 - value of this element set to '1' if the edge is used
at first spanning tree
}
N, M : integer; {the number of vertex, and the number of edges}
FirstAnswer, SecondAnswer : integer; {Answers}
Fi, Fo : Text; {Input and Output file handlers}
Root : integer; { Global variable that used for build of dynamic array}
{Testing procedures}
procedure PrintDynamic;
var i,j : integer;
begin
WriteLn('--- Dynamic ------------');
for i:=1 to n do
begin
for j:=1 to n do
Write(Dynamic[i,j]:4);
WriteLn;
end;
end;
{Working procedures}
{work with list}
procedure ListAdd(i, v, l : integer);
var
p : PList;
begin
New(p);
P^.Next:=BestTree[i];
P^.Ver:=v;
P^.Leng:=l;
BestTree[i]:=P;
end;
procedure ListDispose(p : PList);
begin
if p=nil then exit;
ListDispose(p^.Next);
Dispose(p);
end;
procedure BestTreeDispose;
var i : integer;
begin
for i:=1 to n do
ListDispose(BestTree[i]);
end;
procedure BuildDist;
var i : integer;
begin
Dist[1,1]:=-1;
Dist[1,2]:=-1;
for i:=2 to N do
begin
Dist[i,1]:=A[1,i];
Dist[i,2]:=1;
end;
end;
function MinInt (a, b : integer) : integer;
begin if a<b then MinInt:=a else MinInt:=b;
end;
function MaxInt (a, b : integer) : integer;
begin if a>b then MaxInt:=a else MaxInt:=b;
end;
procedure Init;
var i,x,y,l,j : integer;
begin
for i:=1 to MaxN do BestTree[i]:=nil;
FillChar(A, SizeOf(A), 0); {0 = infinty}
FillChar(Dist, SizeOf(Dist), 0); {0 = infinty}
FillChar(Dynamic, SizeOf(Dynamic), 0);
Assign(Fi, FileIn);
Reset(Fi);
Readln(Fi, N, M);
for i:=1 to M do
begin
ReadLn(Fi, y, x, l);
A[y, x]:=l;
A[x, y]:=l;
end;
Close(Fi);
SecondAnswer:=0;
end;
procedure BuildSpanningTree;
var i,j, MinPos : integer;
begin
FirstAnswer:=0;
BuildDist;
for i:=2 to n do
begin
MinPos:=0;
for j:=1 to n do
if Dist[j, 1]>0 then
if (MinPos=0) then MinPos:=j else
if Dist[j, 1]<Dist[MinPos, 1] then MinPos:=j;
FirstAnswer:=FirstAnswer + Dist[MinPos, 1];
ListAdd(MinPos, Dist[MinPos, 2], Dist[MinPos, 1]);
ListAdd(Dist[MinPos, 2], MinPos, Dist[MinPos, 1]);
Dynamic[MinPos, Dist[MinPos, 2]]:=Dist[MinPos, 1];
Dynamic[Dist[MinPos, 2], MinPos]:=Dist[MinPos, 1];
A[MinPos, Dist[MinPos, 2]]:=-1;
A[Dist[MinPos, 2], MinPos]:=-1;
Dist[MinPos, 1]:=-1;
Dist[MinPos, 2]:=-1;
for j:=1 to n do
if Dist[j, 1]>-1 then
if Dist[j, 1]=0 then
begin
Dist[j, 1]:=A[MinPos, j];
Dist[j, 2]:=MinPos;
end else
if (A[j, MinPos]>0)and(Dist[j, 1]>A[j, MinPos]) then
begin
Dist[j, 1]:=A[MinPos, j];
Dist[j, 2]:=MinPos;
end;
end;
end;
procedure BuildDynamic(Curr, Prev : integer);
var
i : integer;
p : PList;
begin
p:=BestTree[Curr];
while p<>nil do
begin
if (p^.Ver <> Prev) then
begin
Dynamic[Root, p^.Ver]:=MaxInt(p^.Leng, Dynamic[Root, Curr]);
BuildDynamic(p^.Ver, Curr);
end;
p:=p^.Next;
end;
end;
procedure LookForEdge;
var i, j, Calc : integer;
begin
SecondAnswer:=32000;
for i:=1 to N do
for j:=1 to N do
if A[i, j]>0 then
begin
Calc:=(FirstAnswer-Dynamic[i, j]) + A[i, j];
if SecondAnswer>Calc then SecondAnswer:=Calc;
end;
end;
procedure Run;
begin
{first ostov; algorith Prima}
BuildSpanningTree;
{second ostov}
for Root:=1 to n do
BuildDynamic(Root, Root);
{PrintDynamic;} {Test}
LookForEdge;
end;
procedure Done;
begin
BestTreeDispose;
Assign(Fo, FileOut);
Rewrite(Fo);
WriteLn(Fo, FirstAnswer, ' ', SecondAnswer);
Close(Fo);
end;
begin
Init; {Initialization}
Run; {Calculation}
Done; {Printing answer}
end.