走多远(拓扑排序,dp)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector<int> g[N];
int in[N];
int d[N];
int main()
{
int n,m;cin>>n>>m;
while(m--){
int u,v;cin>>u>>v;
u--,v--; // 转换为 0-based 索引
g[u].push_back(v); // 邻接表存边
in[v]++; // 计算入度
}
queue<int> q;
for(int i=0;i<n;i++){
if(in[i]==0){
q.push(i);
}
}
while(q.size()){
int u=q.front();
q.pop();
for(int v:g[u]){
d[v]=max(d[v],d[u]+1); // 更新v的最远距离
if(--in[v]==0){ // 入度减 1,若为 0 入队
q.push(v);
}
}
}
int ans=*max_element(d,d+n); // 获取最大的最远距离
cout<<ans;
return 0;
}
在有向无环图(DAG)中计算从入度为 0 的点出发的最长路径长度。
for (int v : g[u]) {
d[v] = max(d[v], d[u] + 1);
}
这句话表示:"v 的最长路径 = max(当前的 v 的值, 从 u 走来加一条边的值)"
if (--in[v] == 0) {
q.push(v);
}
v 的入度减 1(因为它的一个前驱 u 已经处理完了):如果入度变成 0,说明 v 所有前驱节点都已经处理完了。可以把 v 加进队列,表示继续遍历它指向的下一个节点