zoukankan      html  css  js  c++  java
  • POJ 2186 tarjan+缩点 基础题

    Popular Cows
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 37111   Accepted: 15124

    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. 
     
    题意    n头牛 m个关系 a认为b受欢迎   b认为c受欢迎的话 a也认为c受欢迎 问有多少头牛被其他所有人受欢迎
    解析   我们可以试着去分组 把互相喜欢的人分到一组(组内可以喜欢其他人 但组内人员必须互相喜欢,有向图任意两点相互可达)如果a组内一个人喜欢b组一个人的话  那么就是a组的人都喜欢b组的所有人,但是,就不同时存在b组有人也喜欢a的人,因为如果存在的话a和b就是一个组了。然后我们就可以推出,当且仅当只有一个组x不喜欢其他组时 有答案 答案是这个组的大小否则输出0 
    强联通图缩点,再看下缩完点之后每个点的出度就好了。
      1 #include <stdio.h>
      2 #include <math.h>
      3 #include <string.h>
      4 #include <stdlib.h>
      5 #include <iostream>
      6 #include <sstream>
      7 #include <algorithm>
      8 #include <string>
      9 #include <queue>
     10 #include <map>
     11 #include <vector>
     12 #include <iomanip>
     13 using namespace std;
     14 const int maxn = 1e5+50;
     15 const int maxm = 1e4+10;
     16 const int inf = 0x3f3f3f3f;
     17 const double epx = 1e-10;
     18 typedef long long ll;
     19 const ll INF = 1e18;
     20 const double pi = acos(-1.0);
     21 int mp[maxn];
     22 struct node
     23 {
     24     int v,next;
     25 }edge[maxn];
     26 int dfn[maxn],low[maxn],index,visit[maxn],cnt,tot;
     27 int point[maxn];
     28 int heads[maxn],stack[maxn],num;
     29 void add(int x,int y)
     30 {
     31     edge[++cnt].next=heads[x];
     32     edge[cnt].v=y;
     33     heads[x]=cnt;
     34     return;
     35 }
     36 void tarjan(int x)
     37 {
     38     dfn[x]=low[x]=++tot;
     39     stack[++index]=x;
     40     visit[x]=1;
     41     for(int i=heads[x];i!=-1;i=edge[i].next)
     42     {
     43         if(!dfn[edge[i].v])
     44         {
     45             tarjan(edge[i].v);
     46             low[x]=min(low[x],low[edge[i].v]);
     47         }
     48         else if(visit[edge[i].v])
     49         {
     50             low[x]=min(low[x],dfn[edge[i].v]);
     51         }
     52     }
     53     if(low[x]==dfn[x])
     54     {
     55         do{
     56             int temp=stack[index];
     57             point[temp]=num;
     58             visit[temp]=0;
     59             index--;
     60         }while(x!=stack[index+1]);
     61         num++;
     62     }
     63     return;
     64 }
     65 int main()
     66 {
     67     int n,m;
     68     memset(heads,-1,sizeof(heads));
     69     memset(dfn,0,sizeof(dfn));
     70     memset(low,0,sizeof(low));
     71     memset(mp,0,sizeof(mp));
     72     scanf("%d%d",&n,&m);
     73     tot=cnt=num=index=0;
     74     for(int i=0;i<m;i++)
     75     {
     76         int u,v;
     77         scanf("%d%d",&u,&v);
     78         add(u,v);
     79     }
     80     for(int i=1;i<=n;i++)
     81         if(!dfn[i]) tarjan(i);
     82     int sum=0;
     83     for(int i=1;i<=n;i++)
     84     {
     85         for(int j=heads[i];j!=-1;j=edge[j].next)
     86         {
     87             if(point[i]!=point[edge[j].v])
     88             {
     89                 mp[point[i]]=1;
     90             }
     91         }
     92     }
     93     int cont=0,index;
     94     for(int i=0;i<num;i++)
     95         if(mp[i]==0)
     96         {
     97             cont++,index=i;
     98         }
     99     if(cont==1)
    100     {
    101         int ans=0;
    102         for(int i=1;i<=n;i++)
    103             if(point[i]==index)
    104                 ans++;
    105         cout<<ans<<endl;
    106     }
    107     else
    108         cout<<"0"<<endl;
    109     return 0;
    110 }
    View Code

     推荐两篇博客 https://blog.csdn.net/qq_34374664/article/details/77488976

                             http://blog.miskcoo.com/2016/07/tarjan-algorithm-strongly-connected-components

  • 相关阅读:
    反射学习系列3反射实例应用
    (转)华为牛人在华为工作十年的感悟!
    利用日志记录所有LINQ的增,删,改解决方案
    qt5摄像头
    opencvcartToPolar笛卡尔坐标转极坐标
    逆矩阵
    方阵的行列式
    qt5右键菜单
    矩阵的转置
    opencvpyrDown降采样和pyrUp升采样
  • 原文地址:https://www.cnblogs.com/stranger-/p/8627073.html
Copyright © 2011-2022 走看看