首页 > 其他 > 详细

P1807 最长路

时间:2020-07-19 14:53:37      阅读:42      评论:0      收藏:0      [点我收藏+]

题目:

求图中点1到点n的最长路径

解题思路:

  • 1. 优化的BFS(类似SPFA,只是最小dis变成了最大dis)
  •  逐层遍历,如果遍历到该点时 d + w 大于原来的路径长度,则更新当前路径长度,若该点不在队列中,则加入队列

 

  • 2.将w变成 -W ,求最大路就变成了求最短路

 

  • 3.拓扑排序
  • 只有当某个点所有的入边全部计算后,到该点的最长路才能完全确定,解决了方法 1 中某个点多次入队的问题,
  • 但需要注意: 求的是1 到 n 的最长路径,最开始时入度为0的点一定有1,同时可能有其他的点存在,但这些点不能
  • 加入队列中,因为1可能到不了这些点能到达的点,造成结果错误,但不加入队列也不能放任不管,这些点会造成其后驱结点
  • 的入度比实际计算时要大,正确的做法是将这些第一层除 1 外所有入度为0的点用一次拓扑,将从 1 到不了的多余的边删去,核心代码如下,
  • 进行如下操作后,就可以使用拓扑求结果了
for(int i = 2;i <= n;i++){
   if(num[i] == 0)  //num[i]用于标记点的入度
      q.push(i);  //q是队列
}

  while(!q.empty()){
      int x = q.front();
                 q.pop();
       for(int i = 0;i < a[x].size();i++) //vector<int>a[i] 用于记录出边
         {
                     num[a[x][i]]--;
                      if(num[a[x][i]] == 0)  //当前入度为0,说明1肯定无法到
                                                       //达,因此该点的出边也是无效 
                                                       //边,应当删去
                         q.push(a[x][i]);
  
        }
}

                                                                                  

 

本人用的是第一种方法,代码如下:

#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int MAX = 99999999;
struct node{
    int to;
    int w;
};
int main(){
    int n,m;
    cin >> n >> m;
    vector<struct node> a[n+1];
    int dis[n+1];
    int book[n+1] = {0};
    memset(dis,MAX,sizeof(dis));
    for(int i = 0;i < m;i++){
        int x,y,w;
        cin >> x >> y >> w;
        a[x].push_back((struct node){y,w}); 
    }
    queue<int> q;
    q.push(1);
    book[1] = 1;
    dis[1] = 0;
    while(!q.empty()){
        int x = q.front() ;
        q.pop() ;
        book[x] = 0;
        for(int i = 0;i < a[x].size() ;i++){
              if(dis[a[x][i].to] == MAX)
                   dis[a[x][i].to] = dis[x]+ a[x][i].w;
               else if(dis[a[x][i].to] < dis[x]+ a[x][i].w)  
                        dis[a[x][i].to] = dis[x]+ a[x][i].w;  
        
        if(book[a[x][i].to] == 0){
             q.push(a[x][i].to);
             book[a[x][i].to] = 1; 
        }
        }
    } 
    if(dis[n] == MAX)
    cout << -1;
    else cout << dis[n];
    return 0;
}

 

 

P1807 最长路

原文:https://www.cnblogs.com/LISIYUWANG/p/13338915.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!