社区讨论

90分 求破!

P1608路径统计参与者 8已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mi4f65g1
此快照首次捕获于
2025/11/18 18:17
4 个月前
此快照最后确认于
2025/11/18 18:17
4 个月前
查看原帖
第三个点的路径条数答案不对,求大神解答
贴上代码:
[codep]
CPP
var s,t,len:array[1..4000000]of longint;
var map:array[1..4000000,1..3]of longint;
var first:array[1..2000]of longint;
var heap,f,g,num:array[1..2000]of longint;
var visit:array[1..2000]of boolean;
var i,j,m,n,top,tot,q,tt:longint;
procedure insert(aa,bb,cc:longint);
begin
inc(tot);
map[tot,1]:=bb;
map[tot,2]:=cc;
map[tot,3]:=first[aa];
first[aa]:=tot;
end;
procedure qsort(l,r:longint);//三关键字快排,保证s,t,len三级升序
var i,j,temp,mid1,mid2,mid3:longint;
begin
i:=l;
j:=r;
mid1:=s[(l+r)div 2];
mid2:=t[(l+r)div 2];
mid3:=len[(l+r)div 2];
while i<j do
begin
while (s[i]<mid1)or((s[i]=mid1)and(t[i]<mid2))or((s[i]=mid1)and(t[i]=mid2)and(len[i]<mid3)) do inc(i);
while (s[j]>mid1)or((s[j]=mid1)and(t[j]>mid2))or((s[j]=mid1)and(t[j]=mid2)and(len[j]>mid3)) do dec(j);
if i<=j then
begin
temp:=s[i];
s[i]:=s[j];
s[j]:=temp;
temp:=t[i];
t[i]:=t[j];
t[j]:=temp;
temp:=len[i];
len[i]:=len[j];
len[j]:=temp;
inc(i);
dec(j);
end;
end;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
procedure up(o:longint);//堆up
var gg,temp:longint;
begin
while o>1 do
begin
gg:=o shr 1;
if f[heap[gg]]>f[heap[o]] then
begin
temp:=heap[gg];
heap[gg]:=heap[o];
heap[o]:=temp;
num[heap[gg]]:=gg;
num[heap[o]]:=o;
o:=gg;
end
else break;
end;
end;
procedure down(o:longint);//堆down
var lc,rc,aa,temp:longint;
begin
while o shl 1<=top do
begin
aa:=o;
lc:=o shl 1;
rc:=lc+1;
if (lc<=top)and(f[heap[aa]]>f[heap[lc]]) then aa:=lc;
if (rc<=top)and(f[heap[aa]]>f[heap[rc]]) then aa:=rc;
if aa<>o then
begin
temp:=heap[aa];
heap[aa]:=heap[o];
heap[o]:=temp;
num[heap[aa]]:=aa;
num[heap[o]]:=o;
o:=aa;
end
else break;
end;
end;
begin
read(n,m);
for i:=1 to m do
read(s[i],t[i],len[i]);
qsort(1,m);
for i:=1 to m-1 do//去重,如果i+1和i边完全一样,删掉i
if (s[i]=s[i+1])and(t[i]=t[i+1])and(len[i]=len[i+1]) then
s[i]:=0;
for i:=1 to m do
if (s[i]<>0) then
insert(s[i],t[i],len[i]);//邻接表插边
for i:=1 to n do//初始化
begin
visit[i]:=true;
num[i]:=i;
heap[i]:=i;
g[i]:=0;
f[i]:=100000000;
end;
f[1]:=0;top:=n;
g[1]:=1;
for i:=1 to n do//Dijkstra部分
begin
q:=heap[1];
tt:=first[q];
heap[1]:=heap[top];
dec(top);
down(1);
visit[q]:=false;
while tt<>0 do
begin
if (visit[map[tt,1]])and(f[map[tt,1]]>f[q]+map[tt,2]) then
begin
g[map[tt,1]]:=g[q];
f[map[tt,1]]:=f[q]+map[tt,2];
up(num[map[tt,1]]);
end
else if(visit[map[tt,1]])and(f[map[tt,1]]=f[q]+map[tt,2]) then
g[map[tt,1]]:=g[map[tt,1]]+g[q];
tt:=map[tt,3];
end;
end;
if f[n]=100000000 then writeln('No answer')
else writeln(f[n],' ',g[n]);
end.
[/codep]

回复

7 条回复,欢迎继续交流。

正在加载回复...