最长路问题

  今天校内测,有一道有向无环图的最长路,然后脑子发热交了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.

P1807 最长是一道洛谷的题目,要求计算一个有向无环图中1到n之间的最长径。关于这个问题,可以使用广搜算法来依次搜索图中的结点,并记录当前结点的最长并不断更新。具体的实现可以使用邻接矩阵来存储边权,并注意可能存在重边的情况需要取最大值。此外,为了避免超时,可以在入队时加上一个判断语句,只有当到达该点的最长需要更新时才进行入队操作。以下是一种可能的解法: ```cpp #include <bits/stdc++.h> #define endl '\n' #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const ll mo=80112002; int n, m, u, v, ww, w = max(w[u][v], ww); } q.push(1); memset(a, -1, sizeof(a)); a = 0; while (!q.empty()) { int x = q.front(); q.pop(); for (int i=1; i<=n; i++) { if (w[x][i && a[i < a[x + w[x][i]) { a[i = a[x + w[x][i]; q.push(i); } } } cout << a[n]; return 0; } ``` 以上是一种可能的代码实现,使用了广搜算法来计算最长径。该算法使用邻接矩阵存储边权,通过不断更新当前结点的最长来得到1到n之间的最长径。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [洛谷P1807 最长(BFS)](https://blog.csdn.net/m0_60543948/article/details/126431087)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [图论——最长(洛谷 P1807)](https://blog.csdn.net/weixin_44572229/article/details/120743825)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值