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

  • 相关阅读:
    OpenCV-Python图形图像处理:利用黑帽去除图像浅色水印
    单片机实验四:定时器控制发光二极管的亮灭+简单输出连续矩形脉冲
    实验5 linux网络编程
    第十六届全国大学智能汽车竞赛竞速比赛规则-讨论稿
    写给自己的TypeScript 入门小纲
    写给自己的TypeScript 入门小纲
    Node.js自学笔记之回调函数
    Node.js自学笔记之回调函数
    来简书坚持一个月日更之后
    全选或者单选checkbox的值动态添加到div
  • 原文地址:https://www.cnblogs.com/stranger-/p/8627073.html
Copyright © 2011-2022 走看看