【洛谷2661】信息傳遞 強聯通分量
阿新 • • 發佈:2018-10-01
clas str ems ctype sin add mat edge math
分析
tarjan算出全部的聯通塊,在求出聯通塊裏最小的個數。
AC代碼
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <queue> #include <cctype> #include <cmath> #include <time.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) const int maxn=200010; struct Edge{ int to,next; }edge[maxn<<1]; int nedge,sum,dep,top,n,m,cnt; int head[maxn],dfn[maxn],stack[maxn],low[maxn],od[maxn],vis[maxn],id[maxn]; int belong[maxn],block[maxn]; inline int read() { int X=0,w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } void add_edge(int a,int b) { edge[nedge]=(Edge){b,head[a]}; head[a]=nedge++; } void tarjan(int u) { dfn[u]=low[u]=++dep; stack[top++]=u; vis[u]=1; for (int i=head[u];i!=-1;i=edge[i].next) { int v=edge[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]); } } int j; if (dfn[u]==low[u]) { sum++; do{ j=stack[--top]; belong[j]=sum; vis[j]=0; } while (u!=j); } } int main() { nedge=0; ms(head,-1); n=read(); for (int i=1;i<=n;i++) { int a=read(); add_edge(i,a); } for (int i=1;i<=n;i++) { if (!dfn[i]) tarjan(i); } for (int i=1;i<=n;i++) { block[belong[i]]++; } int ans=maxn; for (int i=1;i<=sum;i++) { if (block[i]!=1) ans=min(block[i],ans); } printf("%d\n",ans); return 0; }
【洛谷2661】信息傳遞 強聯通分量