公路建设(Road.exe, 1s, 64M)
【问题描述】
A国是一个新兴的国家,有N个城市,分别编号为1,2.3…N。政府想大搞公路建设,提供了优惠政策:对于每一个投资方案的预计总费用,政府负担50%,并且允许投资的公司对过往的汽车收取连续5年的养路费。世界各地的大公司纷纷投资,并提出了自己的建设方案,他们的投资方案包括这些内容:公路连接的两座城市的编号,预计的总费用(假设他们的预计总师准确的)。你作为A国公路规划局的总工程师,有权利决定每一个方案是否接受。但是政府给你的要求是:
1)要保证各个城市之间都有公路直接或间接相连。
2)因为是新兴国家,政府的经济实力还不强。政府希望负担最少的费用。
因为大公司并不是同时提出方案,政府希望每接到一个方案,就可以知道当前需要负担的最小费用和接受的投资方案,以便随时开工。关于你给投资公司的回复可以等到开工以后再给。
注意:A国一开始是没有公路的。
【数据说明】A国的城市数目N<=500,投资的方案总数M<=2000。
【输入】输入文件名:Road.in
第1行有两个数字:N、M
第2行到第M+1行给出了各个投资方案,第i行的方案编号为i-1
编号小的方案先接到,一个方案占一行,每行有3个数字,分别是连接的两个城市编号a、b,和投资的预计总费用cost。
【输出】输出文件名:Road.out
输出文件共有M行。
每一行的第一个数字是当前政府需要负担的最少费用(保留1位小数),后面是X个数字,表示当前政府接受的方案的编号,不要求从小到大排列。但如果此时接受的所有投资方案不能保证政府的第一条要求,那么这一行只有一个数字0
【样例】
Road.in | Road.out |
3 5 1 2 4 1 3 4 2 3 4 1 3 2 1 2 2 | 0 4.0 1 2 4.0 1 2 3.0 1 4 2.0 4 5 |
================================
kruskal
===========================
type
node=record
x,y,v,o:longint;
end;
var
n,m:longint;
fa:array[1..250000]of node;
f_fa:array[1..250000]of longint;
fa_s:longint;
map:array[1..500,1..500]of longint;
odd:array[1..500,1..500]of longint;
ans_odd:array[1..250000]of longint;
f_bo:array[1..500]of boolean;
procedure init;
begin
assign(input,'road.in');
assign(output,'road.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function find(x:longint):longint;
begin
if f_fa[x]=x then exit(x)
else begin f_fa[x]:=find(f_fa[x]); exit(f_fa[x]); end;
end;
procedure merge(a,b:longint);
var
x,y:longint;
begin
x:=find(a);
y:=find(b);
f_fa[x]:=y;
end;
procedure qsort(s,t:longint);
var
i,j:longint;
x:longint;
tem:node;
begin
x:=fa[(s+t)shr 1].v;
i:=s; j:=t;
repeat
while x<fa[j].v do dec(j);
while fa[i].v<x do inc(i);
if i<=j then
begin
tem:=fa[i];
fa[i]:=fa[j];
fa[j]:=tem;
inc(i); dec(j);
end;
until i>j;
if i<t then qsort(i,t);
if s<j then qsort(s,j);
end;
procedure main;
var
i,j,k:longint;
x,y,z:longint;
t:longint;
fa_t,ans:longint;
begin
readln(n,m);
fillchar(f_bo,sizeof(f_bo),true);
fillchar(map,sizeof(map),$7);
t:=0;
for i:=1 to m do
begin
readln(x,y,z);
if map[x,y]>z then
begin
map[x,y]:=z;
odd[x,y]:=i;
odd[y,x]:=i;
if f_bo[x] then
begin
f_bo[x]:=false;
inc(t);
end;
map[y,x]:=z;
if f_bo[y] then
begin
f_bo[y]:=false;
inc(t);
end;
end;
if t<n then writeln(0)
else
if t=n then
begin
fa_s:=0;
for j:=1 to n do
for k:=j+1 to n do
if map[j,k]<100000 then
begin
inc(fa_s);
fa[fa_s].x:=j;
fa[fa_s].y:=k;
fa[fa_s].v:=map[j,k];
fa[fa_s].o:=odd[j,k];
end;
qsort(1,fa_s);
for j:=1 to n do f_fa[j]:=j;
fa_t:=0; ans:=0;
for j:=1 to fa_s do
begin
if fa_t=n-1 then break;
if find(fa[j].x)<>find(fa[j].y) then
begin
inc(fa_t);
ans_odd[fa_t]:=fa[j].o;
ans:=ans+fa[j].v;
merge(fa[j].x,fa[j].y);
end;
end;
write(ans/2:0:1,' ');
for j:=1 to fa_t do write(ans_odd[j],' ');
writeln;
end;
end;
end;
begin
init;
main;
terminate;
end.