请柬(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.
在电视时代,没有多少人观看戏剧表演。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.