BZOJ 1051 受欢迎的牛
1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 6731 Solved: 3530 [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 Sample Output 1 HINT 100%的数据N<=10000,M<=50000
这是一道裸题
首先tarjin进行缩点
因为同一强连通分量上的都是互相欣赏的
并且强连通分量上的一个点和别的点相连就代表了这个强连同分量上的所有牛都欣赏那个点的牛
最后判断再缩完点的图中 如果只有一个出度为0的点的话
答案就是那个点的大小,否则就为0
代码
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 inline int read(){ 5 int x=0;int f=1;char ch=getchar(); 6 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 7 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 8 return x*f; 9 } 10 const int MAXN=1e6+10; 11 namespace zhangenming{ 12 struct node{ 13 int x,y,next; 14 }e[MAXN]; 15 int linkk[MAXN],cnt[MAXN]={},len=0,n,m,low[MAXN]={},sum[MAXN]={},dfn[MAXN]={},dfs_clock=0,vis[MAXN]={},belong[MAXN],scc=0,stark[MAXN],top=0; 16 inline void insert(int xx,int yy){ 17 e[++len].y=yy;e[len].x=xx;e[len].next=linkk[xx];linkk[xx]=len; 18 } 19 void init(){ 20 n=read();m=read(); 21 //cout<<n<<' '<<m<<endl; 22 for(int i=1;i<=m;i++){ 23 int xx=read();int yy=read(); 24 insert(xx,yy); 25 } 26 } 27 void tarjin(int st){ 28 //cout<<st<<endl; 29 dfn[st]=low[st]=++dfs_clock; 30 vis[st]=1;stark[++top]=st; 31 for(int i=linkk[st];i;i=e[i].next){ 32 if(!dfn[e[i].y]){ 33 tarjin(e[i].y); 34 low[st]=min(low[st],low[e[i].y]); 35 } 36 else if(vis[e[i].y]) low[st]=min(low[st],dfn[e[i].y]); 37 } 38 if(low[st]==dfn[st]){ 39 scc++; 40 int k; 41 do{ 42 k=stark[top--]; 43 belong[k]=scc; 44 sum[scc]++; 45 vis[k]=0; 46 }while(k!=st); 47 } 48 } 49 void rebuild(){ 50 //cout<<scc<<endl; 51 for(int i=1;i<=len;i++){ 52 int xx=e[i].x;int yy=e[i].y; 53 if(belong[xx]!=belong[yy]){ 54 cnt[belong[xx]]++; 55 } 56 } 57 int ans=0; 58 for(int i=1;i<=scc;i++){ 59 if(!cnt[i]){ 60 if(ans){ 61 ans=0; 62 cout<<0; 63 return; 64 } 65 else ans=sum[i]; 66 } 67 } 68 cout<<ans<<endl; 69 } 70 void solve(){ 71 for(int i=1;i<=n;i++){ 72 if(!dfn[i]) tarjin(i); 73 } 74 rebuild(); 75 } 76 } 77 int main(){ 78 //freopen("All.in","r",stdin); 79 //freopen("a.out","w",stdout); 80 using namespace zhangenming; 81 init(); 82 solve(); 83 return 0; 84 }