强连通分量,缩点

别人的讲解:https://www.cnblogs.com/fripside/p/3587782.html

 

例题1:迷宫城堡 裸的强连通分量

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 11111
int v,ll,top,head[maxn],stack2[maxn],dfn[maxn],low[maxn],cnt,now;
struct re{int a,b;}a[maxn*3];
bool instack[maxn];
void arr(int x,int y)
{
    ll++;
    a[ll].a=head[x];
    a[ll].b=y;
    head[x]=ll;
}
void tarjan(int x)
{
  dfn[x]=low[x]=++now;
  instack[x]=true;
  stack2[++top]=x;
  int u=head[x];
  while (u!=0)
    {
         v=a[u].b;
        if (dfn[v]==-1)
        {
            tarjan(v);
            low[x]=min(low[x],low[v]);
        } else if (instack[v])
          low[x]=min(low[x],dfn[v]);
        u=a[u].a;
  }
  if (dfn[x]==low[x])
  {
      cnt++;
      do 
        {
             v=stack2[top--];
            instack[v]=false;
      } while (v!=x);
  }
} 
int main()
{
    freopen("noip.in","r",stdin);
    freopen("noip.out","w",stdout); 
    std::ios::sync_with_stdio(false);
    int n,m;
  cin>>n>>m;
  while (n!=0)
  {
      memset(dfn,-1,sizeof(dfn));
      memset(head,0,sizeof(head));
      memset(instack,false,sizeof(instack));
      ll=now=cnt=top=0;
      for (int i=1;i<=m;i++)
      {
          int c,d; cin>>c>>d;
          arr(c,d);
      }
      for (int i=1;i<=n;i++)
        if (dfn[i]==-1) tarjan(i);
      if (cnt==1) cout<<"Yes"<<endl; else cout<<"No"<<endl;
      cin>>n>>m;
  }
  return 0;
}
View Code

缩点模板

链接:https://www.luogu.org/problemnew/show/3387

解法:

 

代码:

例题2:Summer Holiday

代码:

 

posted @ 2018-01-09 23:19  尹吴潇  阅读(229)  评论(0编辑  收藏  举报