电话网络(phone)
输入文件:phone.in
输出文件:phone.out
【题目描述】
绿化工程终于完成,整个园区生机勃勃。但是,很不幸的是,在绿化过程中,工人们和进出的车辆将铺设好的电话线全部破坏了。Neyc的领导很生气,问题很严重。为了保住面子,工程队负责人,希望尽快恢复园区的电信,他把这个任务交给了你。
已知,园区周围分布N(1<=n<=1000)根按1…n排列的电话线杆,电话线杆之间可以拉电话线。第i对电话线杆的两个端点分别为Ai,Ri,它们间的距离为Li(1<=li<=1000000)。数据中保证每对最多只出现一次。编号为1的电话线杆已经接入了全国的电话网络,整个园区的电话线全部连到了编号为N的电话线杆上。也就是说,你的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话网络。
绿化工程的负责人与电信公司协商后,电信公司决定免费为园区连接K(0<=k<n)对由你指定的电话线杆。对于此外的那些电话线,就必需为它们付费,总费用等于其中最长的电话线长度(每根电话线仅连接一对电话线杆),其它长度不付费。如果需要连接的电话线杆不超过K对,那么总支出为0。
现在,你就要设计一个费用最少的方案。最后,计算出将电话线引到园区最少需要花多少钱?
【输入格式】
输入文件的第一行包含三个用空格隔开的整数:N ,P和K。
第二行到第P+1行:每行分别都为三个用空格隔开的整数:Ai Bi和Li。
【输出格式】
输出文件仅包含一个整数,表示在这项工程上的最小支出。如果任务不可能完成,则输出-1。
【样例输入】
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
【样例输出】
4
=======================
二分加最短路
可以二分出一个答案,构建最短路模型,若cost>mid则之间的花费就是1.
若dis[n]>k返回false,否则返回true
----------------------------------------------
最开始用的是二分加搜索,就爆了5个点
function check(t_,times:longint):boolean;
var
p:node;
flag:boolean;
begin
check:=false;
if t_=n then exit(true);
p:=t[t_];
while p<>nil do
begin
if (p^.cost<=mid)and(f[p^.x]) then
begin
f[p^.x]:=false;
flag:=check(p^.x,times);
if flag then exit(true);
f[p^.x]:=true;
end;
if (p^.cost>mid) and (times>0) and f[p^.x] then
begin
f[p^.x]:=false;
flag:=check(p^.x,times-1);
if flag then exit(true);
f[p^.x]:=true;
end;
p:=p^.next;
end;
end;
=======================
type
node=^re;
re=record
x,cost:longint;
next:node;
end;
var
n,p,k:longint;
t:array[1..1000]of node;
f,v:array[1..1000]of boolean;
dis:array[1..1000]of longint;
h:array[1..100000]of longint;
l,r,mid,ans:longint;
procedure init;
begin
assign(input,'phone.in');
assign(output,'phone.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure insert(a,b,c:longint);
var
p:node;
begin
new(p);
p^.x:=b;
p^.cost:=c;
p^.next:=t[a];
t[a]:=p;
end;
function spfa:boolean;
var
p:node;
l,r:longint;
begin
v[1]:=true; dis[1]:=0;
l:=0; r:=1;
h[1]:=1;
repeat
inc(l);
p:=t[h[l]];
v[h[l]]:=false;
while p<>nil do
begin
if p^.cost<=mid then
begin
if dis[h[l]]<dis[p^.x] then
begin
dis[p^.x]:=dis[h[l]];
if not v[p^.x] then
begin
v[p^.x]:=true;
inc(r);
h[r]:=p^.x;
end;
end;
end;
if p^.cost>mid then
begin
if dis[h[l]]+1<dis[p^.x] then
begin
dis[p^.x]:=dis[h[l]]+1;
if not v[p^.x] then
begin
v[p^.x]:=true;
inc(r);
h[r]:=p^.x;
end;
end;
end;
p:=p^.next;
end;
until l>r;
if dis[n]-k>0 then exit(false)
else exit(true);
end;
procedure main;
var
i:longint;
a,b,c,tot:longint;
begin
readln(n,p,k);
for i:=1 to n do
t[i]:=nil;
tot:=0;
for i:=1 to p do
begin
readln(a,b,c);
if tot<c then tot:=c;
insert(a,b,c);
insert(b,a,c);
end;
l:=0; r:=tot;
ans:=-1;
while l<=r do
begin
fillchar(f,sizeof(f),true);
mid:=(l+r)shr 1;
fillchar(v,sizeof(v),false);
fillchar(dis,sizeof(dis),$7);
if spfa then begin ans:=mid; r:=mid-1; end
else l:=mid+1;
//f[1]:=false;
//times:=k;
//if check(1,k) then begin ans:=mid; r:=mid-1; end
//else l:=mid+1;
end;
writeln(ans);
end;
begin
init;
main;
terminate;
end.