【POJ3180 奶牛舞会】

题目大意:

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

样例输入: 

  5 4
  2 4
  3 5
  1 2
  4 1

样例输出:

  1

题解

  一句话题意。给定一个有向图,问有多少个大于等于2的强联通分量。多组数据,练习模板清空数组。

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cstdio>
 5 using namespace std;
 6 struct node
 7 {
 8     int next,to;
 9 }    e[100005];
10 int head[10005],dfn[10005],low[10005],cnt,time,s[10005];
11 int vis[10005],ans;
12 inline void insert(int u,int v)
13 {
14     e[++cnt].next=head[u];
15     head[u]=cnt;
16     e[cnt].to=v;
17 }
18 inline void tarjan(int now)
19 {
20     dfn[now]=low[now]=++time;
21     s[++s[0]]=now;vis[now]=1;
22     for(int i=head[now];i;i=e[i].next)
23     {
24         if(!dfn[e[i].to])
25         {
26             tarjan(e[i].to);
27             low[now]=min(low[now],low[e[i].to]);
28         }
29         else    if(vis[e[i].to])
30             low[now]=min(low[now],dfn[e[i].to]);
31     }
32     if(low[now]==dfn[now])
33     {
34         int num=1;
35         vis[now]=0;
36         while(s[s[0]]!=now)
37         {
38             vis[s[s[0]]]=0;
39             num++;
40             s[0]--;
41         }
42         s[0]--;
43         if(num>=2)    ans++;
44     }
45 }
46 int main()
47 {
48     int n,m,u,v;
49     while(scanf("%d%d",&n,&m)!=EOF)
50     {
51         memset(dfn,0,sizeof(dfn));
52         memset(low,0,sizeof(low));
53         memset(head,0,sizeof(head));
54         memset(s,0,sizeof(s));
55         cnt=0,time=0,ans=0;
56         for(int i=1;i<=m;i++)
57         {
58             scanf("%d%d",&u,&v);
59             insert(u,v);
60         }
61         for(int i=1;i<=n;i++)
62             if(!dfn[i])    tarjan(i);
63         printf("%d\n",ans);
64     }
65     return 0;
66 }

 

转载于:https://www.cnblogs.com/Dndlns/p/7858068.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值