【强连通分量】Bzoj1654 [Usaco2006 Jan]The Cow Prom 奶牛舞会

Description

    约翰的N(2≤N≤10000)只奶牛非常兴奋,因为这是舞会之夜!她们穿上礼服和新鞋子,别上鲜花,她们要表演圆舞.

    只有奶牛才能表演这种圆舞.圆舞需要一些绳索和一个圆形的水池.奶牛们围在池边站好,顺时针顺序由1到N编号.每只奶牛都面对水池,这样她就能看到其他的每一只奶牛.为了跳这种圆舞,她们找了M(2≤M≤50000)条绳索.若干只奶牛的蹄上握着绳索的一端,绳索沿顺时针方绕过水池,另一端则捆在另一些奶牛身上.这样,一些奶牛就可以牵引另一些奶牛.有的奶牛可能握有很多绳索,也有的奶牛可能一条绳索都没有对于一只奶牛,比如说贝茜,她的圆舞跳得是否成功,可以这样检验:沿着她牵引的绳索,找到她牵引的奶牛,再沿着这只奶牛牵引的绳索,又找到一只被牵引的奶牛,如此下去,若最终能回到贝茜,则她的圆舞跳得成功,因为这一个环上的奶牛可以逆时针牵引而跳起旋转的圜舞.如果这样的检验无法完成,那她的圆舞是不成功的.
    如果两只成功跳圆舞的奶牛有绳索相连,那她们可以同属一个组合.
    给出每一条绳索的描述,请找出,成功跳了圆舞的奶牛有多少个组合?
 

Sulotion

裸强连通分量,我就测试下模板。。

 

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=1e5+5;
 5 
 6 int pre[maxn],low[maxn],clock;
 7 int bcc[maxn],size[maxn],cnt;
 8 int head[maxn],e[maxn],nxt[maxn],k;
 9 int adde(int u,int v){
10     e[++k]=v,nxt[k]=head[u];
11     head[u]=k;
12 }
13 int a[maxn],t;
14 int n,m;
15 
16 int dfs(int u){
17     pre[u]=low[u]=++clock;
18     a[++t]=u;
19     for(int i=head[u];i;i=nxt[i]){
20         int v=e[i];
21         if(!pre[v]){
22             dfs(v);
23             low[u]=min(low[u],low[v]);
24         }
25         else if(!bcc[v]){
26             low[u]=min(low[u],pre[v]);
27         }
28     }
29     if(low[u]==pre[u]){
30         ++cnt;
31         while(t){
32             bcc[a[t]]=cnt;
33             size[cnt]++;
34             if(a[t--]==u) break;
35         }
36     }
37 }
38 
39 int main(){
40     scanf("%d%d",&n,&m);
41     int u,v;
42     for(int i=1;i<=m;i++){
43         scanf("%d%d",&u,&v);
44         adde(u,v);
45     }
46     
47     for(int i=1;i<=n;i++)
48         if(!pre[i]) dfs(i);
49         
50     int ans=0;
51     for(int i=1;i<=cnt;i++)
52         if(size[i]>1) ans++;
53     printf("%d\n",ans);
54     
55     return 0;
56 }

 

posted @ 2015-06-04 11:42  CyanNode  阅读(492)  评论(0编辑  收藏  举报