强连通分量,缩点
别人的讲解: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; }
缩点模板
链接:https://www.luogu.org/problemnew/show/3387
解法:
代码:
例题2:Summer Holiday
代码: