P2341 [HAOI2006]受欢迎的牛

题面。。(我好困啊。。。)

这题的想法确实很巧妙,由于只有除自身外所有奶牛都爱慕奶牛a时,a才是明星奶牛,那么很显然,这说明不可能存在两个不同的强连通分量里都是出度为0,即为明星奶牛的情况,那样就不可能使除自己外所有奶牛爱慕同一强连通分量中的奶牛,so,tarjan+缩点+倒叙查找

代码实现:

 1 #include<set>
 2 #include<map>
 3 #include<list>
 4 #include<queue>
 5 #include<stack>
 6 #include<string>
 7 #include<cmath>
 8 #include<ctime>
 9 #include<vector>
10 #include<bitset>
11 #include<memory>
12 #include<utility>
13 #include<cstdio>
14 #include<sstream>
15 #include<iostream>
16 #include<cstdlib>
17 #include<cstring>
18 #include<algorithm>
19 using namespace std;
20 const int N=50005;
21 
22 int n,m,tot,top,z,num,ans,an;
23 int to[N],next[N],head[N],dfn[N],low[N],d[N],s1[N],s2[N],zy[N];
24 
25 inline void add(int x,int y){//加边
26     to[++tot]=y;
27     next[tot]=head[x];
28     head[x]=tot;
29 }
30 
31 void tarjan(int u){//tarjan+缩点
32     dfn[u]=low[u]=++num;
33     s2[++top]=u;
34     for(int i=head[u];i;i=next[i]){
35         int v=to[i];
36         if(!dfn[v]){
37             tarjan(v);
38             low[u]=min(low[u],low[v]);
39         }
40         else{
41             if(!zy[v]){
42                 low[u]=min(low[u],dfn[v]);
43             }
44         }
45     }
46     if(low[u]==dfn[u]){
47         zy[u]=++z;
48         s1[z]++;
49         while(s2[top]!=u){
50             ++s1[z];
51             zy[s2[top]]=z;
52             top--;
53         }
54         top--;
55     }
56 }
57 
58 int main(){
59     int n,m;
60     scanf("%d%d",&n,&m);
61     for(int i=1;i<=m;i++){
62         int x,y;
63         scanf("%d%d",&x,&y);
64         add(y,x);
65     }
66     for(int i=1;i<=n;i++){
67         if(!dfn[i]){
68             tarjan(i);
69         }
70     }
71     for(int i=1;i<=n;i++){//遍历每个节点的出度
72         for(int j=head[i];j;j=next[j]){
73             if(zy[i]!=zy[to[j]]){
74                 d[zy[to[j]]]++;
75             }
76         }
77     }
78     for(int i=1;i<=z;i++){
79         if(!d[i]){//若出度为0,记录
80             ans=s1[i];
81             an++;
82         }
83     }
84     if(an==1){
85         printf("%d\n",ans);
86     }
87     else{//多个出度为0则无明星奶牛
88         printf("0\n");
89     }
90     return 0;
91 }

嗯我要睡觉了白白

 

posted @ 2019-07-10 01:42  喵呜,颜儿ღ  阅读(128)  评论(0编辑  收藏  举报