图
现在有一个N个点的有向图,每个点仅有一条出边
你需要求出图中最长的简单路径包含点的数量(1≤N≤1,000,000)
输入描述:
第一行一个数字N
接下来N行,每行一个正整数,第i+1行的数字表示第i个点出边终点的编号
(点从1开始标号)
输出描述:
一行一个数字,最长的简单路径的长度
这道题就是先拓扑排序求出各个点的(其实就是支链)最长长度,然后拓扑没有遍历到的点也就是环上的点,找出这些点在遍历一遍,找出环上的点能连接的最长长度和环的大小,
为啥要遍历所有没有遍历的点,因为这题的图可以是不连通的,也就是说可以有多个环;
代码:
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
#define inf 0x3f3f3f3f
//ios::sync_with_stdio(false);
using namespace std;
const int N=1000100;
const int M=1000100;
const ll mod=998244353;
int in[N];
int n;
struct Node{
int to,nex;
}edge[N*2];
int head[N];
int cnt;
void add(int p,int q){
edge[cnt].to=q;
edge[cnt].nex=head[p];
head[p]=cnt++;
}
int dp[N];
queue<int>qu;
bool vis[N];
void bfs(){
while(!qu.empty()){
int u=qu.front();
vis[u]=true;
qu.pop();
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].to;
dp[v]=max(dp[v],dp[u]+1);
in[v]--;
if(in[v]==0) qu.push(v);
}
}
}
int sum,mmax;
bool f[N];
void dfs(int p){
f[p]=true;
mmax=max(mmax,dp[p]);//最长支链大小
sum++;//环的大小
for(int i=head[p];~i;i=edge[i].nex){
int u=edge[i].to;
if(!f[u]) dfs(u);
}
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++){
int q;
cin>>q;
add(i,q);
in[q]++;//入度
}
for(int i=1;i<=n;i++){
dp[i]=1;
if(in[i]==0) qu.push(i);
}
bfs();
int ans=0;
for(int i=1;i<=n;i++){
if(!vis[i]&&!f[i]){
sum=mmax=0;
dfs(i);
ans=max(ans,sum+mmax-1);
}
}
cout<<ans<<endl;
return 0;
}