【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受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
Input
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
3 3
1 2
2 1
2 3
1 2
2 1
2 3
Sample Output
1
HINT
100%的数据N<=10000,M<=50000
很久之前做过的一道题目。。
具体就是先tarjan缩点,点的权值就是这个连通分量的点的数量
然后找入度为0的点
只有一个就输出它的权值
多个就输0
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 6 #define maxn 10001 7 8 using namespace std; 9 10 inline int In() 11 { 12 int x=0;char ch=getchar(); 13 while(ch<'0'||ch>'9')ch=getchar(); 14 while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); 15 return x; 16 } 17 18 struct ed{ 19 int u,v; 20 }edge[maxn*5]; 21 22 struct node{ 23 int to,last; 24 }e[maxn*10]; 25 26 int last[maxn],tot=0,dfn[maxn],low[maxn],father[maxn],sta[maxn],top=0,cnt=0,size=0,num[maxn],in[maxn]; 27 28 bool ins[maxn]; 29 30 void add(int u,int v){e[++tot].to=v,e[tot].last=last[u],last[u]=tot;} 31 32 void tarjan(int poi) 33 { 34 dfn[poi]=low[poi]=++cnt; 35 ins[poi]=1;sta[++top]=poi; 36 for(int i=last[poi];i;i=e[i].last) 37 { 38 int u=e[i].to; 39 if(!dfn[u]) 40 { 41 tarjan(u); 42 low[poi]=min(low[u],low[poi]); 43 } 44 else if(ins[u]) low[poi]=min(low[poi],dfn[u]); 45 } 46 if(dfn[poi]==low[poi]) 47 { 48 size++; 49 int vv; 50 do{ 51 vv=sta[top]; 52 father[vv]=size; 53 ins[vv]=0; 54 num[size]++; 55 top--; 56 }while(vv!=poi); 57 } 58 } 59 60 int main() 61 { 62 freopen("1051.in","r",stdin); 63 int n,m,str=0; 64 n=In(),m=In(); 65 for(int i=1;i<=n;i++)father[i]=i; 66 for(int i=1;i<=m;i++) 67 edge[i].u=In(),edge[i].v=In(),add(edge[i].u,edge[i].v); 68 for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i); 69 memset(last,0,sizeof(last)); 70 tot=0; 71 for(int i=1;i<=m;i++)if(father[edge[i].u]!=father[edge[i].v]){ 72 in[father[edge[i].u]]++; 73 } 74 for(int i=1;i<=size;i++) 75 { 76 if(!in[i]&&str){printf("0");return 0;} 77 if(!in[i])str=i; 78 } 79 printf("%d",num[str]); 80 return 0; 81 }