最长路问题

  今天校内测,有一道有向无环图的最长路,然后脑子发热交了spfa的,被学长思想教育了一番,学长说有向无环图最长路拓扑排序肯定是比spfa优的,然后就很傻地说我做过一题spfa更优,后来回去翻到了题,发现那是个无向图,妥妥地实力打脸。

  题目描述大概是讲一群小孩分糖果,开始糖果在一个人手里,第一秒开始手上有糖的人美秒把糖分给周围的人,每个人拿到糖后都用同样C的时间吃糖(吃糖和发糖是可以同时进行的),问开始到最后一个人吃完糖要多久(人数≤10^5,关系数≤2*10^6,保证不重复)

  显然,答案是最长路+C

  不多说,放代码

 var ans,tot,n,e,m,s,head,tail:longint;
     dist,que,link:array[0..100005]of longint;
     w,son,next:array[0..2000005]of longint;
     vis:array[0..100005]of boolean;
 procedure add(x,y,z:longint);
  begin
   inc(tot);w[tot]:=z;son[tot]:=y;next[tot]:=link[x];link[x]:=tot;
  end;
 procedure init;
  var x,y,i:longint;
   begin
    assign(input,'candy.in');reset(input);
    assign(output,'candy.out');rewrite(output);
    fillchar(link,sizeof(link),0);
    tot:=0;
    readln(n,e,s);
    readln(m);
    for i:=1 to e do
     begin
      readln(x,y);
      add(x,y,1);
      add(y,x,1);
     end;
   end;
 procedure spfa;
  var xx,j:longint;
   begin
    fillchar(dist,sizeof(dist),63);
    fillchar(vis,sizeof(vis),0);
    fillchar(que,sizeof(que),0);
    que[1]:=s;dist[s]:=0;vis[s]:=true;
    head:=0;tail:=1;
    while head<>tail do
     begin
      head:=(head+1) mod 100005;
      xx:=que[head];
      vis[xx]:=false;
      j:=link[xx];
      while j<>0 do
       begin
        if dist[xx]+w[j]<dist[son[j]] then begin
                                            dist[son[j]]:=dist[xx]+w[j];
                                            if not vis[son[j]] then begin
                                                                     vis[son[j]]:=true;
                                                                     tail:=(tail+1) mod 100005;
                                                                     que[tail]:=son[j];
                                                                    end;
                                           end;
        j:=next[j];
       end;
      end;
   end;
 procedure print;
  var i:longint;
   begin
    ans:=-maxlongint;
    for i:=1 to n do
     if dist[i]>ans then ans:=dist[i];
    writeln(ans+1+m);
    close(input);close(output);
   end;
 begin
  init;
  spfa;
  print;
 end.

  Bingo!

【写的有漏洞的,欢迎路过大神吐槽】

  2016-11-6 23:16:23

 Ending.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值