1. 程式人生 > >bzoj1654 / P2863 [USACO06JAN]牛的舞會The Cow Prom

bzoj1654 / P2863 [USACO06JAN]牛的舞會The Cow Prom

P2863 [USACO06JAN]牛的舞會The Cow Prom

求點數$>1$的強連通分量數,裸的Tanjan模板。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int min(int &a,int &b){return a<b?a:b;}
 6 #define N 10002
 7 #define M 50002 
 8 int n,m,clo,dfn[N],low[N],blo,be[N],tp,st[N],ans;
9 int cnt,hd[N],nxt[M<<1],ed[N],poi[M<<1]; 10 void adde(int x,int y){ 11 nxt[ed[x]]=++cnt; hd[x]=hd[x]?hd[x]:cnt; 12 ed[x]=cnt; poi[cnt]=y; 13 } 14 void tarjan(int x){ 15 dfn[x]=low[x]=++clo; st[++tp]=x; 16 for(int i=hd[x];i;i=nxt[i]){ 17 int to=poi[i]; 18
if(!dfn[to]){ 19 tarjan(to); 20 low[x]=min(low[x],low[to]); 21 }else if(!be[to]) low[x]=min(low[x],dfn[to]); 22 } 23 if(dfn[x]<=low[x]){ 24 int tot=1; 25 be[x]=++blo; 26 while(st[tp]!=x) be[st[tp--]]=blo,++tot; 27 --tp; ans+=(tot>1
); 28 } 29 } 30 int main(){ 31 scanf("%d%d",&n,&m); 32 for(int i=1,q1,q2;i<=m;++i) 33 scanf("%d%d",&q1,&q2),adde(q1,q2); 34 for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i); 35 printf("%d",ans); 36 return 0; 37 }
View Code