【BZOJ1051】受欢迎的牛

强连通分量:

首先tarjan缩点重构图

之后,若出度为0的点仅有一个,那么答案即为该点代表的强连通分量中点的个数

否则,答案为0

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 const int N=10010,M=50010;
 5 const int novis=-1,over=1,nowvis=0;
 6 int size,head[M],next[M],to[M];
 7 int head2[M],next2[M],to2[M];
 8 int low[N],dfn[N],flag[N],color[N],que[N],sum[N],
 9     top,cnt,n,m,sig;
10 void tarjan(),uni(int,int),dfs(int),rebuild();
11 int find(),min(int,int);
12 int main(){
13     int ans,x,y;
14     size=0;
15     memset(head,0,sizeof(head));
16     memset(head2,0,sizeof(head2));
17     scanf("%d %d",&n,&m);
18     for (int i=1;i<=m;i++){
19         scanf("%d %d",&x,&y);
20         uni(x,y);
21     }
22     tarjan();
23     rebuild();
24     ans=find();
25     printf("%d",ans);
26     return 0;
27 }
28 void uni(int x,int y){
29     size++;
30     next[size]=head[x];
31     head[x]=size;
32     to[size]=y;
33 }
34 void tarjan(){
35     memset(flag,novis,sizeof(flag));
36     memset(color,0,sizeof(color));
37     memset(sum,0,sizeof(sum));
38     sig=cnt=top=0;
39     for (int i=1;i<=n;i++)
40         if (flag[i]==novis) dfs(i);
41 }
42 void dfs(int x){
43     que[++top]=x;
44     flag[x]=nowvis;
45     low[x]=dfn[x]=++sig;
46     for (int e=head[x];e;e=next[e]){
47         int v=to[e];
48         if (flag[v]==novis){
49             dfs(v);
50             low[x]=min(low[x],low[v]);
51         }
52         else if (flag[v]==nowvis)
53             low[x]=min(low[x],dfn[v]);
54     }
55     if (low[x]==dfn[x]){
56         int t;cnt++;
57         do{
58             t=que[top--];
59             color[t]=cnt;
60             flag[t]=over;
61             sum[cnt]++;
62         }while (t!=x);
63     }
64 }
65 void rebuild(){
66     size=0;
67     for (int u=1;u<=n;u++){
68         for (int e=head[u];e;e=next[e]){
69             int v=to[e];
70             if (color[u]!=color[v]){
71                 size++;
72                 next2[size]=head2[color[u]];
73                 head2[color[u]]=size;
74                 to2[size]=color[v];
75             }
76         }
77     }
78 }
79 int find(){
80     int ans=0;
81     for (int i=1;i<=cnt;i++)
82         if (!head2[i]){
83             if (ans) return 0;
84             else ans=sum[i];
85         }
86     return ans;
87 }
88 int min(int x,int y){
89     return x<y?x:y;
90 }

STD

时间: 2024-10-13 11:15:15

【BZOJ1051】受欢迎的牛的相关文章

【bzoj1051】 [HAOI2006]受欢迎的牛 tarjan缩点判出度算点数

[bzoj1051] [HAOI2006]受欢迎的牛 2014年1月8日7450 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B) Output

bzoj1051【HAOI2006】受欢迎的牛

1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3491  Solved: 1837 [Submit][Status][Discuss] Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. I

[BZOJ1051] [HAOI2006] 受欢迎的牛 (强联通分量)

Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头 牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可 能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的. Sample Input 3

【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的. Sample Input 3 3

【强连通分量】Bzoj1051 HAOI2006 受欢迎的牛

Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Solution 那么对于x如果可以也就是所有节点都可以到达x,如果无环也就是x要无出度且无出度的点数正好为1(出边连点必到不了x). 然而这是有环的,那么把强连通分量缩起来就行了. Code 我这个傻逼现在才会求强连通分量. 而且还

bzoj1051 [HAOI2006]受欢迎的牛

1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MB Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头 牛被所有的牛认为是受欢迎的. Input 第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可

BZOJ1051|HAOI2006受欢迎的牛|强连通分量

Description每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的.Input第一行两个数N,M. 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)Output一个数,即有多少头牛被所有的牛认为是受欢迎的.Sample Input3 31 22 12

HAOI2006 受欢迎的牛

HAOI2006 ]受欢迎的牛 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛 A 认为牛 B受欢迎.这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Input 第1行两个整数N,M: 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B) Output 一个数,即有多少头牛被所有的牛认为是受欢迎的

【tarjan】BZOJ 1051:受欢迎的牛

1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3134  Solved: 1642[Submit][Status][Discuss] Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头牛被所有的牛认为是受欢迎的. Inp

[BZOJ 1051][HAOI 2006]受欢迎的牛(tarjan缩点)

http://www.lydsy.com:808/JudgeOnline/problem.php?id=1051 唔...这题好像在POJ上见过? 比较水的题,很好想出思路.牛和牛之间的关系就像有向图,牛a喜欢牛b相当于建立有向边a->b,然后在这个有向图中,每个强连通分量里的牛们相当于是相互喜欢的,把这个图缩点成DAG,DAG里如果有且仅有一个出度为0的点,则这个点对应强连通分量里的所有牛都是受欢迎的牛,如果没有出度为0的点,当然就没受欢迎的牛了,如果出度为0的点的个数大于1,则每个出度为0的