Grouping ZOJ - 3795

题意:缩点找最长链

#include <bits/stdc++.h>

using namespace std;
#define N 100005
int dp[N],vis[N],f[N];
vector<int>path[N],son[N];
stack<int>q;
int dep[N],low[N],tot,cnt;
void tarjan(int u)
{
    dep[u]=low[u]=vis[u]=++tot;
    q.push(u);
    for(int i=0;i<path[u].size();i++){
        int to=path[u][i];
        if(!dep[to]){
            tarjan(to);
            low[u]=min(low[u],low[to]);
        }
        else if(vis[to])low[u]=min(low[u],dep[to]);
    }
    if(dep[u]!=low[u])return;
    cnt++;
    while(1){
        int to=q.top();q.pop();
        f[to]=cnt;
        son[cnt].push_back(to);
        vis[to]=0;
        if(to==u)break;
    }
}
int dfs(int x)
{
    if(vis[x])return dp[x];
    vis[x]=1;
    for(int i=0;i<son[x].size();i++)
        for(int j=0;j<path[son[x][i]].size();j++)
            dp[x]=max(dp[x],dfs(f[path[son[x][i]][j]]));
    return dp[x]+=son[x].size();
}
void init(int n){
    for(int i=1;i<=n;i++)dp[i]=0,path[i].clear(),vis[i]=0,dep[i]=0,son[i].clear();
    tot=cnt=1;
}
int main()
{
    int m,n,u,to;
    while(scanf("%d %d",&n,&m)!=EOF){
        init(n);
        while(m--){
            scanf("%d %d",&u,&to);
            if(u!=to)path[u].push_back(to);
        }
        int ans=1;
        for(int i=1;i<=n;i++)
            if(!dep[i])tarjan(i);
        for(int i=1;i<=n;i++)
        {
            if(!vis[f[i]])dfs(f[i]);
            ans=max(ans,dp[f[i]]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值