- 标签:图论,拓扑,dp
题意
给定一张 \(n\) 个点 \(m\) 条边的 DAG,对于每个 \(i\),求以它为终点最多经过多少个点?
思路
由于是 DAG,求的是终点 \(i\) 经过的所有点,而刚好拓扑序就满足这个。
那么就可以考虑拓扑排序。
设 \(f_i\) 是以 \(i\) 为终点的最多结点数,那么就有转移方程 \(f_v=max(f_v,f_u+1)\)。
在拓扑排序过程中,所有入度为 \(0\) 的 \(v\),\(v\) 可以从其它节点过来,也就是它的前驱 \(u\)。
即 \(u\) 的方案数 \(f_u\) 再加 \(1\)。
当然初始化时对于所有入度为 \(0\) 的 \(u\),\(f_u=1\)。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,x,y,in[N],f[N];
vector<int> g[N];
void topo(){
queue<int> q;
for(int i=1;i<=n;i++) if(in[i]==0) q.push(i),f[i]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(auto i:g[u]){
if(--in[i]==0){
f[i]=f[u]+1;
q.push(i);
}
}
}
}
signed main(){
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>x>>y;
g[x].push_back(y),in[y]++;
}
topo();
for(int i=1;i<=n;i++) cout<<f[i]<<endl;
return 0;
}
标签:终点,洛谷,个点,int,题解,拓扑,P1137
From: https://www.cnblogs.com/Jessie-Pu/p/18162609