玛丽卡(spfa)求指导
pascal吧
全部回复
仅看楼主
level 11
百星高照 楼主
var
n,m,i,a,b,t,head,tail,max,j:longint;
cost,sost:array[1..1000,1..1000] of longint;
dist:array[1..1000] of longint;
v:array[1..1000] of boolean;
q,p:array[1..1000] of longint;
procedure spfa(a,b:longint);
var x:longint;
begin
fillchar(v,sizeof(v),false);fillchar(q,sizeof(q),0);
for i:=1 to n do dist[i]:=maxlongint div 3;
head:=0;tail:=1;
v[a]:=true;q[tail]:=a;dist[a]:=0;
while head<>tail do
begin
head:=(head mod n)+1;
x:=q[head];
for i:=1 to n do
if (cost[x,i]>0) and (cost[x,i]+dist[x]<dist[i]) then
begin
dist[i]:=cost[x,i]+dist[x];
p[i]:=x;
if not(v[i]) then
begin
tail:=(tail mod n)+1;
q[tail]:=i;
v[i]:=true;
end;
end;
end;
if dist[1]>max then max:=dist[1];
end;
procedure spfa2(a,b:longint);
var x:longint;
begin
fillchar(v,sizeof(v),false);fillchar(q,sizeof(q),0);
for i:=1 to n do dist[i]:=maxlongint div 3;
head:=0;tail:=1;
v[a]:=true;q[tail]:=a;dist[a]:=0;
while head<>tail do
begin
head:=(head mod n)+1;
x:=q[head];
for i:=1 to n do
if (cost[x,i]>0) and (cost[x,i]+dist[x]<dist[i]) then
begin
dist[i]:=cost[x,i]+dist[x];
if not(v[i]) then
begin
tail:=(tail mod n)+1;
q[tail]:=i;
v[i]:=true;
end;
end;
end;
if dist[1]>max then max:=dist[1];
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(a,b,t);
cost[a,b]:=t;
cost[b,a]:=t;
end;
spfa(n,1);
max:=0;
j:=1;
while j<>n do
begin
sost[j,p[j]]:=cost[j,p[j]];
cost[j,p[j]]:=maxlongint div 3;
cost[p[j],j]:=maxlongint div 3;
spfa2(n,1);
cost[j,p[j]]:=sost[j,p[j]];
cost[p[j],j]:=sost[j,p[j]];
j:=p[j];
end;
writeln(max);
end.
2015年07月22日 02点07分 1
level 11
百星高照 楼主
只能过5个点,其他的答案错误
测试点#marica1.in 结果:AC内存使用量: 256kB 时间使用量: 1ms
测试点#marica10.in 结果:WA内存使用量: 4716kB 时间使用量: 645ms
测试点#marica2.in 结果:AC内存使用量: 256kB 时间使用量: 1ms
测试点#marica3.in 结果:WA内存使用量: 256kB 时间使用量: 0ms
测试点#marica4.in 结果:AC内存使用量: 368kB 时间使用量: 1ms
测试点#marica5.in 结果:WA内存使用量: 492kB 时间使用量: 1ms
测试点#marica6.in 结果:AC内存使用量: 620kB 时间使用量: 2ms
测试点#marica7.in 结果:WA内存使用量: 1004kB 时间使用量: 8ms
测试点#marica8.in 结果:AC内存使用量: 2412kB 时间使用量: 85ms
测试点#marica9.in 结果:WA内存使用量: 4080kB 时间使用量: 193ms
2015年07月22日 02点07分 2
level 11
百星高照 楼主
大神在哪里
2015年07月22日 09点07分 4
level 14
看你是新手在用邻接表。。然后我也逗比一样的用邻接表,明知道稠密图不好用spfa又嫌堆+dijkstra麻烦,就水一发。。结果TLE滚粗。。
我就知道,最近我好像越来越大条了,水题都刷不动了555。
然后优化①改边表②修改的边于最初的最短路上。于是水过。。
具体代码:
const
oo=$3f3f3f3f;
var
n,m,i,e,u,v,w,ans:longint;
d,f,head,last,edge:array[0..1005]of longint;
q,next,node,cost,flag:array[0..2000005]of longint;
g:array[0..1005,0..1005]of longint;
procedure sw(var a,b:longint);
var c:longint; begin c:=a; a:=b; b:=c end;
procedure ad(u,v,w:longint);
begin
inc(e);
next[e]:=head[u];
head[u]:=e;
node[e]:=v;
cost[e]:=w
end;
procedure spfa(s:longint);
var
i,u,v,l,r:longint;
begin
fillchar(d,sizeof(d),$3f);
fillchar(f,sizeof(f),0);
d[s]:=0;
l:=0;
r:=1;
q[1]:=s;
repeat
inc(l);
u:=q[l];
f[u]:=0;
i:=head[u];
while i>0 do
begin
v:=node[i];
if flag[i]<2 then
if d[v]>d[u]+cost[i] then
begin
d[v]:=d[u]+cost[i];
last[v]:=u;
edge[v]:=i;
if f[v]=0 then
begin
inc(r);
q[r]:=v;
f[v]:=1
end
end;
i:=next[i]
end;
until l=r;
if d[n]>ans then ans:=d[n]
end;
begin
read(n,m);
for i:=1 to m do
begin
read(u,v,w);
ad(u,v,w);
ad(v,u,w)
end;
spfa(1);
u:=n;
while last[u]>0 do
begin
flag[edge[u]]:=1;
u:=last[u]
end;
for i:=1 to e do
if flag[i]=1 then
begin
flag[i]:=2;
spfa(1);
flag[i]:=1
end;
write(ans)
end.
2015年07月22日 15点07分 5
对了那个oo和sw过程是上次写余留下来的没用的请忽略。其它有什么不懂的敬请提问
2015年07月22日 15点07分
@139457820 大神,能不能帮我在过程前加点注释,帮我理解下
2015年07月25日 06点07分
level 14
2015年07月25日 09点07分 6
大神,不知道你有没有发现这是你第二次教我了
2015年07月25日 12点07分
肯定不介意我再问一个
2015年07月25日 12点07分
你不是让我注释么。。
2015年07月25日 14点07分
level 11
百星高照 楼主
题目描述 Description
给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目
数据范围:N<=105。Ai<=105。时间限制为1s。
输入描述 Input Description
第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。
输出描述 Output Description
所有逆序对总数.
2015年07月25日 12点07分 7
用树状数组优化。。我试了试,可能是水不太满,只过了3个点,别的全部爆时间
2015年07月25日 12点07分
为什么问我这种水题。。
2015年07月25日 14点07分
这不树状数组秒之么。。
2015年07月25日 14点07分
level 14
var
n,i,t:longint;
a,f:array[0..100005]of longint;
procedure ad(x:longint);
begin
while x<=100000 do
begin
inc(f[x]);
inc(x,x and(-x))
end
end;
function sm(x:longint):longint;
begin
sm:=0;
while x>0 do
begin
inc(sm,f[x]);
dec(x,x and(-x))
end
end;
begin
read(n);
for i:=1 to n do read(a[i]);
for i:=n downto 1 do
begin
t:=t+sm(a[i]);
ad(a[i])
end;
write(t)
end.
2015年07月25日 14点07分 8
随手写的比较丑。但是这树状数组能超时我也真是汗颜。。
2015年07月25日 14点07分
还有,别没事叫我大神。我这种蒟蒻都是大神的话,那些金牌爷我只能说是六维世界的神了。。
2015年07月25日 14点07分
@139457820 好吧,= =,那。。大师。。?我好多东西都是新学的,正在夏令营,所以问题都有点水,别介意。。
2015年07月26日 11点07分
@139457820 我把你的程序测试了一遍,在codevs 1688里把所有变量改成int64后只对了1个点。。对了,这个程序里的逆序对是怎么判处来的[疑问]
2015年07月26日 11点07分
level 14
哦。。int64是我的疏忽我承认了。看来是我脑子是瓦特了。。
不过原来题目里没说每个数都不一样。。主要以前离散化习惯了,忘记了。那很简单,只要把sm(a[i])改成sm(a[i]-1)即可。
2015年07月26日 12点07分 13
嗯。。不过你也太心急了,我之前那个程序连样例都过不了口牙。。
2015年07月26日 12点07分
另外的话,我感觉在Pascal吧里谈竞赛的东西不怎么好,你如果不介意的话,直接加我QQ。名字+6=我QQ,注明是P吧的就好
2015年07月26日 12点07分
@139457820 嗯嗯,谢谢,不过这里机房的电脑内存不太好= =,下个QQ会卡死,我试试,如果没成功,那31号回去会加你。
2015年07月27日 10点07分
回复
���Ǹ���
:不客气。
2015年07月27日 10点07分
1