洛谷 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];
}

 

posted @ 2017-09-11 15:49  一蓑烟雨任生平  阅读(144)  评论(0编辑  收藏  举报