• 洛谷 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

    思路:spfa求最长路。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 50001
    using namespace std;
    queue<int>que;
    int n,m,tot,vis[MAXN],dis[MAXN];
    int to[MAXN],cap[MAXN],net[MAXN],head[MAXN];
    void add(int u,int v,int w){
        to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot;
    }
    void spfa(int s){
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        que.push(s);
        vis[s]=1;dis[s]=0;
        while(!que.empty()){
            int now=que.front();
            que.pop();
            vis[now]=0;
            for(int i=head[now];i;i=net[i])
                if(dis[to[i]]<dis[now]+cap[i]){
                    dis[to[i]]=dis[now]+cap[i];
                    if(!vis[to[i]]){
                        vis[to[i]]=1;
                        que.push(to[i]);
                    }
                }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        spfa(1);
        if(dis[n]==0)    cout<<"-1";
        else cout<<dis[n];
    }

    思路:拓扑排序求最长路。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 50001
    using namespace std;
    queue<int>que;
    int n,m,tot,into[MAXN],dis[MAXN];
    int to[MAXN],cap[MAXN],net[MAXN],head[MAXN];
    void add(int u,int v,int w){
        to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot;
    }
    void bfs(int s){
        while(!que.empty())    que.pop();
        que.push(s);
        while(!que.empty()){
            int now=que.front();
            que.pop();
            for(int i=head[now];i;i=net[i])
                if(dis[now]+cap[i]>dis[to[i]]){
                    dis[to[i]]=dis[now]+cap[i];
                    que.push(to[i]);
                }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            into[y]++;
        }
        for(int i=2;i<=n;i++)
            if(into[i]==0)
                que.push(i);
        while(!que.empty()){
            int now=que.front();
            que.pop();
            for(int i=head[now];i;i=net[i]){
                into[to[i]]--;
                if(!into[to[i]])
                    que.push(to[i]);
            }
        }
        if(into[n]==0){
            cout<<"-1";
            return 0;
        }
        bfs(1);
        cout<<dis[n];
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    好的学习资源
    对paper有用的idea
    斜杠青年
    简书随笔
    点云专业英文单词
    通过 UDP 发送数据的简单范例
    简单的聊天时范例(客户端)
    键盘输入
    简单的传输文件范例
    编写serversocket简单示例1
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7505339.html
Copyright © 2020-2023  润新知