zoukankan      html  css  js  c++  java
  • 洛谷 P1807 最长路_NOI导刊2010提高(07)

    题目描述

    设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j。设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径。

    输入输出格式

    输入格式:
    输入文件longest.in的第一行有两个整数n和m,表示有n个顶点和m条边,接下来m行中每行输入3个整数a,b,v(表示从a点到b点有条边,边的长度为v)。

    输出格式:
    输出文件longest.out,一个整数,即1到n之间的最长路径.如果1到n之间没连通,输出-1。

    输入输出样例

    输入样例#1:
    2 1
    1 2 1
    输出样例#1:
    1

    说明

    20%的数据,n≤100,m≤1000

    40%的数据,n≤1,000,m≤10000

    100%的数据,n≤1,500,m≤50000,最长路径不大于10^9


    题解

    做法:拓扑排序+DAG上dp
    这题还算是水题,拓扑排序去掉入度为1的点,然后就可以用bfs来做dp了,转移方程也很明显:
    dj=max(dj,di+wi,j)(i,j)
    关于这题为什么要拓扑排序,好像是不做拓扑排序就会在dp的时候出各种问题。。
    下来贴代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    #include<queue>
    using namespace std;
    struct edge{
        int to,w;
        edge(int y,int l):to(y),w(l){}
    };
    int n,m;
    vector<edge> G[1501];
    int d[1501];
    int du[1501];
    void addedge(int x,int y,int l){
        G[x].push_back(edge(y,l));
        du[y]++;
    }
    void toposort(int s){
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0;i<G[x].size();i++){
                edge &e=G[x][i];
                du[e.to]--;
                if(du[e.to]==0){
                    q.push(e.to);
                }
            }
            G[x].clear();
        }
    }
    void bfs(int s){
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0;i<G[x].size();i++){
                edge &e=G[x][i];
                if(d[x]+e.w>d[e.to]){
                    d[e.to]=d[x]+e.w;
                    q.push(e.to);
                }
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y,l;
            scanf("%d%d%d",&x,&y,&l);
            addedge(x,y,l);
        }
        for(int i=2;i<=n;i++){
            if(du[i]==0){
                toposort(i);
            }
        }
        if(du[n]==0){
            printf("-1");
            return 0;
        }
        bfs(1);
        printf("%d",d[n]);
        return 0;
    }
  • 相关阅读:
    MSIL实用指南-一维数组的操作
    MSIL实用指南-给字段、属性、方法、类、程序集加Attribute
    MSIL实用指南-比较运算
    MSIL实用指南-逻辑运算
    MSIL实用指南-位运算
    MSIL实用指南-数学运算
    MSIL实用指南-创建对象
    MSIL实用指南-装箱拆箱
    MSIL实用指南-生成构造函数
    K8S从入门到放弃系列-(5)kubernetes集群之kube-apiserver部署
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581282.html
Copyright © 2011-2022 走看看