tarjan缩点+拓扑排序为什么会错呀
查看原帖
tarjan缩点+拓扑排序为什么会错呀
210945
Liam_楼主2020/9/23 20:47
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
int ru[N],chu[N];
int cnt[N];
queue<int>q;


int dfn[N],low[N],vis[N],stk[N],color[N],du[N];
int top,deep;
vector<int> g[N],mp[N],fa;
int book[N];
void tarjan(int u)
{
    dfn[u]=low[u]=++deep;
    vis[u]=1;
    stk[++top]=u;
    int sz=g[u].size();
    for(int i=0; i<sz; i++)
    {
        int v=g[u][i];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else
        {
            if(vis[v])
            {
                low[u]=min(low[u],low[v]);
            }
        }
    }
    if(dfn[u]==low[u])
    {
        int cnt=1;
        color[u]=u;
        vis[u]=0;
        fa.push_back(u);
        while(stk[top]!=u)
        {
            color[stk[top]]=u;
            vis[stk[top--]]=0;
            cnt++;
        }
        book[u]=cnt;
        top--;
    }
}
int viss[N];
int main()
{
    int n,m;
    int x,y;
    scanf("%d%d",&n,&m);
    //memset(cnt,1,sizeof cnt);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        g[x].push_back(y);
    }
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i])
            tarjan(i);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=0,k=g[i].size();j<k;j++)
        {
            if(color[i]!=color[g[i][j]])
            {

                mp[color[i]].push_back(color[g[i][j]]);
                ru[color[g[i][j]]]++;
                chu[color[i]]++;
            }
        }
    }
    /*int ans=0;
    for(int i=0,j=fa.size();i<j;i++)
    {
        if(chu[color[fa[i]]]==0)
        {
            if(ans)
            {
                cout<<0<<endl;
                return 0;
            }
            else
            {
                ans=color[fa[i]];
            }
        }
    }
    cout<<book[ans]<<endl;
    return 0;*/
    for(int i=0,j=fa.size();i<j;i++)
    {
        if(ru[fa[i]]==0)
        {
            q.push(fa[i]);
            viss[fa[i]]=1;
        }
    }

    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        viss[u]=0;
        for(int i=0,j=mp[u].size();i<j;i++)
        {
            ru[mp[u][i]]--;
            book[mp[u][i]]+=book[u];
            if(ru[mp[u][i]]==0)
            {
                if(viss[mp[u][i]]==0)
                {
                    q.push(mp[u][i]);
                    viss[mp[u][i]]=1;
                }

            }
        }
    }
    int ans=0;
    /*for(int i=0,j=fa.size();i<j;i++)
    {
        if(book[fa[i]]==n)
        {
            ans+=book[fa[i]];
        }
    }*/
    for(int i=1;i<=n;i++)
    {
        if(book[color[i]]==n)
        {
            ans++;
        }
    }
    cout<<ans<<endl;
}

tarjan缩点+拓扑排序为什么会错呀 先进行缩点,在用拓扑排序计数为什么会错呀

2020/9/23 20:47
加载中...