• P1807 最长路(拓扑排序)


    一道裸的dag拓扑排序,vector模拟邻接表存出边和权值,dp数组更新最长路。

    /*
     展开
    题目描述
    
    设 G 为有 n 个顶点的带权有向无环图,G 中各顶点的编号为 1 到 n,请设计算法,计算图 GG 中 <1,n><1,n> 间的最长路径。
    
    输入格式
    
    输入的第一行有两个整数,分别代表图的点数 n 和边数 m。
    
    第 2 到第 (m+1) 行,每行 3 个整数 u, v,w,代表存在一条从 u 到 v 边权为w的边。
    
    输出格式
    
    输出一行一个整数,代表 1 到 n 的最长路。
    
    若 1 与 n 不联通,请输出 -1。
    */
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e4+5;
    int indge[maxn],dp[maxn],bj[maxn];
    int n,m;
    vector<pair<int,int> >v[maxn];
    void topsort()
    {
        queue<int>q;
        while(!q.empty())q.pop();
        for(int i=1;i<=n;i++){
            if(!indge[i])q.push(i);
        }
        while(!q.empty()){
            int k=q.front();q.pop();
            for(int i=0;i<v[k].size();i++){
                if(--indge[v[k][i].first]==0)q.push(v[k][i].first);
                if(bj[k]){
                    dp[v[k][i].first]=max(dp[v[k][i].first],dp[k]+v[k][i].second);///自身的长度与父亲节点的最长路加上父亲到儿子这条边的长度比较
                    bj[v[k][i].first]=1;
                 }
            }
        }
    }
    int main()
    {
        cin>>n>>m;
        int a,b,c;
        memset(indge,0,sizeof(indge));
        memset(dp,0,sizeof(dp));
        memset(bj,0,sizeof(bj));
        for(int i=0;i<m;i++){
            cin>>a>>b>>c;
            v[a].push_back(make_pair(b,c));
            indge[b]++;
        }
        dp[n]=-1,bj[1]=1;///初始化dp[n]=-1,输出方便,bj[1]=1,标记1能到达点
        topsort();
        cout<<dp[n]<<endl;
        return 0;
    }
  • 相关阅读:
    在本地连接服务器上的mysql数据库
    js提取字符串中的数值
    下载安装mysql
    git最基础操作二(clone)
    点击页面出现富强、民主
    解决wepacke配置postcss-loader时autoprefixer失效问题
    li之间产生的间隙问题的解决方法
    webpack简单体验
    apply、call和bind
    remote Incorrect username or password ( access token)问题解决
  • 原文地址:https://www.cnblogs.com/mohari/p/12915037.html
Copyright © 2020-2023  润新知