以下两份代码:
#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]);
}