2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 H题 skiing(拓扑排序)

在DAG上用拓扑排序求最长最短路似乎十分常见,我在做一道cf的题目时无意间看到这题

这题要求的是最长路,因此用拓扑序来求,为什么可以用拓扑序呢?

因为我们对于每个点,都会跟他相连的点被更新,因此就可以通过max操作,直到所有点被更新完,才会将他入队,那么这个点的最终值也就被确定

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
int in[N];
vector<pll> g[N];
int f[N];
int n;
void topo(){
    queue<int> q;
    int i;
    for(i=1;i<=n;i++){
        if(!in[i]){
            q.push(i);
        }
    }
    memset(f,0,sizeof f);
    while(q.size()){
        int t=q.front();
        q.pop();
        for(i=0;i<g[t].size();i++){
            int j=g[t][i].first;
            int tmp=g[t][i].second;
            in[j]--;
            if(!in[j])
                q.push(j);
            f[j]=max(f[j],f[t]+tmp);
        }
    }
}
int main(){
    int t;
    int m;
    cin>>t;
    while(t--){
        cin>>n>>m;
        int i;
        for(i=1;i<=n;i++)
            g[i].clear();
        memset(in,0,sizeof in);
        for(i=1;i<=m;i++){
            int u,v;
            int c;
            scanf("%d%d%d",&u,&v,&c);
            g[u].push_back(pll{v,c});
            in[v]++;
        }
        topo();
        int res=-1;
        for(i=1;i<=n;i++){
            res=max(res,f[i]);
        }
        cout<<res<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/ctyakwf/p/12633179.html