关于tarjan算法
  • 板块学术版
  • 楼主lxzy_
  • 当前回复4
  • 已保存回复4
  • 发布时间2020/6/3 14:13
  • 上次更新2023/11/7 01:14:46
查看原帖
关于tarjan算法
67493
lxzy_楼主2020/6/3 14:13

以下两份代码:

#include<cstdio>
#include<iomanip>
#include<stack>
using namespace std;
const int N=1e3+50;
stack<int> st;
struct edge{
    int to;
    int nxt;
}a[N];
int head[N];
int DFN[N];
int Low[N];
bool vis[N];
int n,m,idx;
int cnt;
 
void add(int u,int v)
{
    cnt++;
    a[cnt].to=v;
    a[cnt].nxt=head[u];
    head[u]=cnt;
}
void Tarjan(int u)
{
    DFN[u]=Low[u]=++idx;
    st.push(u);
    vis[u]=true;
    for(int i=head[u];i;i=a[i].nxt)
    {
        int v=a[i].to;
        if(!DFN[v])
        {
            Tarjan(v);
            Low[u]=min(Low[u],Low[v]);
        }
        else
        {
            if(vis[v])
            {
                Low[u]=min(Low[u],DFN[v]);
            }
        }
    }
 
    if(DFN[u]==Low[u])
    {
        vis[u]=false;
        while(st.top()!=u&&!st.empty())
        {
            vis[st.top()]=false;
            printf("%d ",st.top());
            st.pop();
        }
        if(st.top()==u)
        {
            printf("%d ",u);
            st.pop();
        }
        printf("\n");
    }
}           
int main()
{
    scanf("%d%d",&n,&m);
    int u,v;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        add(u,v);
    }
 
    for(int i=1;i<=n;i++)
    {
        if(!DFN[i])
        {
            Tarjan(i);
        }
    }
    return 0;
}

and

#include<cstdio>
#include<iomanip>
#include<stack>
using namespace std;
const int N=1e3+50;
stack<int> st;
struct edge{
    int to;
    int nxt;
}a[N];
int head[N];
int DFN[N];
int Low[N];
bool vis[N];
int n,m,idx;
int cnt;
 
void add(int u,int v)
{
    cnt++;
    a[cnt].to=v;
    a[cnt].nxt=head[u];
    head[u]=cnt;
}
void Tarjan(int u)
{
    DFN[u]=Low[u]=++idx;
    st.push(u);
    vis[u]=true;
    for(int i=head[u];i;i=a[i].nxt)
    {
        int v=a[i].to;
        if(!DFN[v])
        {
            Tarjan(v);
            Low[u]=min(Low[u],Low[v]);
        }
        else
        {
            
          
                Low[u]=min(Low[u],DFN[v]);
             
        }
    }
 
    if(DFN[u]==Low[u])
    {
        vis[u]=false;
        while(st.top()!=u&&!st.empty())
        {
            vis[st.top()]=false;
            printf("%d ",st.top());
            st.pop();
        }
        if(st.top()==u)
        {
            printf("%d ",u);
            st.pop();
        }
        printf("\n");
    }
}           
int main()
{
    scanf("%d%d",&n,&m);
    int u,v;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        add(u,v);
    }
 
    for(int i=1;i<=n;i++)
    {
        if(!DFN[i])
        {
            Tarjan(i);
        }
    }
    return 0;
}

第一份代码AC,为什么第二份代码却格式错误呢?

还有就是执行tarjan的时候遍历点u的联通点v的时候为什么一定要加上:

if(vis[v])
{
    Low[u]=min(Low[u],DFN[v]);
}
2020/6/3 14:13
加载中...