Luogu P1137 旅行计划
可以发现,因为只能往东边走,并且有入度为$0$的起点,因此这是一个有向无环图,可以进行拓扑排序,求出拓扑序列。
那么我们要拓扑序列怎么做呢?由于拓扑序列中,前面的点总是后面的点的前驱,因此可以进行DP。
而DP的状态转移方程也很明显,这个城市只能由前面的城市转移过来,因此有方程:$$dis[v]=max(dis[v],dis[u]+1)$$
#include<bits/stdc++.h>
#define N 100010
#define M 200010
using namespace std;
int n,m,cnt;
int deg[N],head[N],dis[N];
struct node {
int nxt,to;
}edge[M];
void addEdge(int u,int v) {
edge[++cnt]=(node){head[u],v};
head[u]=cnt;
deg[v]++;
return;
}
void Read() {
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) {
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
}
return;
}
void Init() {
for(int i=1;i<=n;i++) {
dis[i]=1;
}
return;
}
void Topo() {
queue <int> q;
for(int i=1;i<=n;i++) {
if(deg[i]==0) {
q.push(i);
}
}
while(!q.empty()) {
int x=q.front();
q.pop();
for(int i=head[x];i;i=edge[i].nxt) {
int t=edge[i].to;
deg[t]--;
if(deg[t]==0) {
dis[t]=dis[x]+1;
q.push(t);
}
}
}
return;
}
void Print() {
for(int i=1;i<=n;i++) {
printf("%d
",dis[i]);
}
return;
}
int main()
{
Read();
Init();
Topo();
Print();
return 0;
}