zoukankan      html  css  js  c++  java
  • POJ 2168 Popular cows [Tarjan 缩点]

                                                                                                               Popular Cows
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 39115   Accepted: 15937

    Description

    Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
    popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

    Input

    * Line 1: Two space-separated integers, N and M

    * Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

    Output

    * Line 1: A single integer that is the number of cows who are considered popular by every other cow.

    Sample Input

    3 3
    1 2
    2 1
    2 3
    

    Sample Output

    1
    

    Hint

    Cow 3 is the only cow of high popularity.
     
    Tarjan入门题,果然有的算法入门题就需要应用啊。。
    求强连通分量的板子差不多找到个舒服的了,为了速度起见还是不用STL了吧。
    这个题,问有没有点能被其他所有的点到达。强连通分量中是各自满足条件的
    由于有向无环图中,出度为零的点是满足这个条件的。所以我们可以使用tarjan来找到所有的强连通分量,并进行缩点,对强连通分量进行编号,把每个点标记一下所属于的强连通分量,然后把图遍历一下,求出每个强连通分量的出度。
    最后判断出度为0的强连通分量个数,若为1个,则存在,输出编号为这个的点个数即可。否则不存在。
      1   #include<cstdio>
      2   #include<cstring>
      3   #include<iostream>
      4   #include<cstdlib>
      5   #include<algorithm>
      6   #include<cmath>
      7   #include<vector>
      8   #include<stack>
      9   //#include<bits/stdc++.h>
     10   using namespace std;
     11   #define mem(a,b) memset(a,b,sizeof(a))
     12   #define ll long long
     13   #define inf 1000000000
     14   #define maxn 10005
     15   #define maxm 100005
     16   #define eps 1e-10
     17   #define for0(i,n) for(int i=1;i<=(n);++i)
     18   #define for1(i,n) for(int i=1;i<=(n);++i)
     19   #define for2(i,x,y) for(int i=(x);i<=(y);++i)
     20   #define for3(i,x,y) for(int i=(x);i>=(y);--i)
     21   #define mod 1000000007
     22   inline int read()
     23   {
     24       int x=0,f=1;char ch=getchar();
     25       while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
     26       while(ch>='0'&&ch<='9') {x=10*x+ch-'0';ch=getchar();}
     27       return x*f;
     28   }
     29   struct node{
     30     int to,next;
     31   }edge[maxm];
     32   int n,m,head[maxn],vis[maxn],dfn[maxn],low[maxn],du[maxn],num[maxn],cnt,timi,stack1[maxn],top,cut;
     33   void init()
     34   {
     35       memset(dfn,0,sizeof(dfn));
     36       memset(low,0,sizeof(low));
     37       memset(head,-1,sizeof(head));
     38       memset(vis,0,sizeof(vis));
     39       memset(num,0,sizeof(num));
     40       memset(du,0,sizeof(du));
     41       cnt=0;
     42       timi=1;
     43       top=0;
     44       cut=0;
     45   }
     46   stack <int> s;
     47   void addedge(int u,int v)
     48   {
     49       edge[cnt].to=v;
     50       edge[cnt].next=head[u];
     51       head[u]=cnt;
     52       cnt++;
     53   }
     54   void tarjan(int u)
     55   {
     56     dfn[u]=timi;
     57     low[u]=timi;
     58     timi++;
     59     s.push(u);
     60     //stack1[top]=u;top++;
     61     vis[u]=1;
     62     for(int i=head[u];i!=-1;i=edge[i].next)
     63     {
     64       int v=edge[i].to;
     65       if(!dfn[v]) {
     66         tarjan(v);
     67         low[u]=min(low[u],low[v]);
     68       }
     69       else{
     70         low[u]=min(low[u],dfn[v]);
     71       }
     72     }
     73       if(low[u]==dfn[u])
     74       {
     75         cut++;
     76         int x=s.top();
     77         while(!s.empty()&&x!=u)
     78         {
     79             vis[s.top()]=0;
     80             //vis[stack1[top]]=2;
     81             num[s.top()]=cut;
     82             s.pop();
     83             x=s.top();
     84         }
     85         num[s.top()]=cut;
     86         s.pop();
     87       }
     88     }
     89   int main()
     90   {
     91     int a,b;
     92     while(~scanf("%d%d",&n,&m))
     93     {
     94       init();
     95       for(int i=1;i<=m;++i)
     96         {scanf("%d%d",&a,&b);
     97           addedge(a,b);
     98           }
     99       for(int i=1;i<=n;++i)
    100       {
    101         if(!dfn[i]) tarjan(i); 
    102       }
    103       for(int i=1;i<=n;++i)
    104       {
    105         for(int j=head[i];j!=-1;j=edge[j].next)
    106         {
    107           if(num[i]!=num[edge[j].to]) {du[num[i]]++;
    108           }
    109         }
    110       }
    111       int sum=0,x;
    112       for(int i=1;i<=cut;++i)
    113       {
    114         if(!du[i]) {sum++;x=i;}
    115       }
    116       if(sum==1)
    117       {
    118         sum=0;
    119         for(int i=1;i<=n;++i) 
    120             if(num[i]==x) sum++;
    121         printf("%d
    ",sum);
    122       }
    123       else puts("0
    ");
    124     }
    125     return 0;
    126   }
    View Code
  • 相关阅读:
    vim how to set nu with 0-index instead of 1-index
    @property的介绍与使用
    X[:,0]和X[:,1]
    the best guide for git
    sorted(列表)
    Java的匿名函数
    成员变量和局部变量的区别
    Java数组合并
    Java中random的使用
    Git常见错误---git branch不显示本地分支的问题
  • 原文地址:https://www.cnblogs.com/TYH-TYH/p/9389751.html
Copyright © 2011-2022 走看看