简单tarjan》一道裸题(BZOJ1051)(easy)

这是一道水题,实际考察的是你会不会写强连通分量。。。(在BZOJ上又水了一道题)

 

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
1 2
2 1
2 3

Sample Output

1

HINT

100%的数据N<=10000,M<=50000
 
思路:直接强连通分量缩点,然后,因为题目没有告诉你  当没有一头牛受欢迎时  应该输出什么,所以我们认为题目一定有解,所以直接tarjan就好啦
强行给出代码
 1 #include<stdio.h>
 2 #include<string.h>
 3 int head[11000],F[11000],w[11000],ass,stack[11000],n,point,m,D[11000],ans;
 4 int min(int x,int y)
 5 {
 6     return x>y?y:x;
 7 }
 8 bool f[11000];
 9 struct shit{
10     int aim,next,from;
11 }e[51000];
12 int T,time[51000],dfn[51000];
13 void tarjan(int x)
14 {
15     time[x]=dfn[x]=++T;
16     f[x]=true;
17     stack[++ass]=x;
18     for(int k=head[x];k;k=e[k].next)
19     {
20         int v=e[k].aim;
21         if(!time[v])
22         {
23             tarjan(v);
24             dfn[x]=min(dfn[x],dfn[v]);
25         }
26         else if(f[e[k].aim])dfn[x]=min(dfn[x],time[v]);
27     }
28     if(dfn[x]==time[x])
29     {
30         f[x]=false;
31         while(stack[ass]!=x)
32         {
33             w[x]++;
34             F[stack[ass]]=x;
35             f[stack[ass--]]=false;
36         }
37         ass--;
38     }
39 }
40 void fuck(int x,int y)
41 {
42     e[++point].aim=y;
43     e[point].from=x;
44     e[point].next=head[x];
45     head[x]=point;
46 }
47 int main()
48 {
49     int a,b;
50     scanf("%d%d",&n,&m);
51     for(int i=1;i<=m;++i)
52     {
53         scanf("%d%d",&a,&b);
54         fuck(a,b);
55     }
56     for(int i=1;i<=n;++i)F[i]=i,w[i]=1;
57     for(int i=1;i<=n;++i)
58     if(!time[i])tarjan(i);
59     memset(head,0,sizeof(head));
60     point=0;
61     for(int i=1;i<=m;++i)
62     {
63         if(F[e[i].from]==F[e[i].aim])continue;
64         else {
65             D[F[e[i].from]]++;
66             fuck(F[e[i].aim],F[e[i].from]);
67         }
68     }
69     for(int i=1;i<=n;i++)
70         if(F[i]==i&&!D[i])ans+=w[i];
71     printf("%d",ans);
72     return 0;
73 }
View Code

没什么好PS的

posted @ 2016-09-27 21:27  PencilWang  阅读(293)  评论(0编辑  收藏  举报