您的位置:首页 > 其它

请柬(invite)

2015-05-29 19:07 288 查看
【问题描述】
在电视时代,没有多少人观看戏剧表演。Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片。他们已经打印请帖和所有必要的信息和计划。许多学生被雇来分发这些请柬。每个学生志愿者被指定一个确切的公共汽车站,他或她将留在那里一整天,邀请人们参与。

  这里的公交系统是非常特殊的:所有的线路都是单向的,连接两个站点。公共汽车离开起始点,到达目的地之后又空车返回起始点。 

学生每天早上从总部出发,乘公交车到一个预定的站点邀请乘客。每个站点都被安排了一名学生。在一天结束的时候,所有的学生都回到总部。现在需要知道的是,学生所需的公交费用的总和最小是多少。

【输入文件】

第1行有两个整数n、m(1<=n,m<=1000000),n是站点的个数,m是线路的个数。

然后有m行,每行描述一个线路,包括3个整数,起始点,目的地和价格。

总部在第1个站点,价钱都是整数,且小于1000000000。

【输出文件】

输出一行,表示最小费用。

【样例输入】

4 6

1 2 10

2 1 60

1 3 20

3 4 10

2 4 5

4 1 50

【样例输出】

210

【样例解释】

学生各自从总部被派遣到2,3,4站点,然后又回到总部

1-2-4-1:10+5+50=65

1-3-4-1:20+10+50=80

1-2-4-1:10+5+50=65

65+80+65=210

【注意】

此题数据规模较大,需要使用较为高效的算法,此题不设小规模数据分数。

建立双向图然后两次单源最短路,用dijkstra+heap练练手
program zhen;
type
sonlink=^node;
node=record
e:longint;
v:int64;
next:sonlink;
end;
var
son:array[0..1000000,1..2]of sonlink;
dist:array[0..1000000]of int64;
heap,hpos:array[0..1000000]of longint;
i,j,n,m,len:longint;
ans:int64;
procedure init_data;
var
i,x,y,v:longint;
p:sonlink;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y,v);
new(p);
p^.v:=v;
p^.e:=y;
p^.next:=son[x,1];son[x,1]:=p;
new(p);
p^.v:=v;
p^.e:=x;
p^.next:=son[y,2];son[y,2]:=p;
end;
end;
procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end;
procedure sifup(s:longint);
var
p:longint;
begin
while s>1 do
begin
p:=s shr 1;
if dist[heap[p]]>dist[heap[s]] then
begin
hpos[heap[p]]:=s;hpos[heap[s]]:=p;
swap(heap[p],heap[s]);
end
else
break;
s:=p;
end;
end;
procedure sifdown(p:longint);
var
s:longint;
begin
while p shl 1<=len do
begin
s:=p shl 1;
if (s<len) and (dist[heap[s+1]]<dist[heap[s]]) then inc(s);
if dist[heap[p]]>dist[heap[s]] then
begin
hpos[heap[p]]:=s;hpos[heap[s]]:=p;
swap(heap[p],heap[s]);
end
else
break;
p:=s;
end;
end;

procedure extract_min;
begin
heap[1]:=heap[len];
hpos[heap[1]]:=1;
dec(len);
sifdown(1);
end;
procedure dijkstra(x:longint);
var
i,j,k:longint;
t:int64;
p:sonlink;
begin
dist[1]:=0;
for i:=2 to n do dist[i]:=1000000000000;
len:=n;
for i:=1 to n do
begin
hpos[i]:=i;
heap[i]:=i;
end;
for i:=1 to n do
begin
k:=heap[1];
extract_min;
p:=son[k,x];
while p<>nil do
begin
t:=dist[k]+p^.v;
if t<dist[p^.e] then
begin
dist[p^.e]:=t;
sifup(hpos[p^.e]);
end;
p:=p^.next;
end;
end;
for i:=2 to n do
ans:=ans+dist[i];
end;

begin
assign(input,'invite.in');reset(input);
assign(output,'invite.out');rewrite(output);

init_data;
ans:=0;
dijkstra(1);
dijkstra(2);
writeln(ans);

close(input);close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: