zoukankan      html  css  js  c++  java
  • haoi2006_受欢迎的牛_Solution

    Brief Solution:

    强连通tarjan+压缩点+判断是否除了一个点,其它点都有出度

    Detailed Solution:

    把牛看成点
    若一个点b能到达点a,则b认为a受欢迎
    若所有的点都能到达点a,则a被所有的牛欢迎

    对于某个强连通中的点,任意两点可互达,互相受欢迎
    对图求强连通,并把强连通压缩成一个点
    若点a向与点a不在同一个强连通集合的点b,则点a所在的集合指向点b所在的集合(边)

    若一个强连通集合的点(新图的点A)能被所有的点到达,则新图所有的点能到达点A
    此时新图没有环,若一个点A能被所有的点到达,则除了该点,其它点的出度都不为0(图必有没有出度的点,因为图没有环)
    则能被所有的点到达的点只有一个,否则会有环,矛盾
    (在没有环的条件下,图中所有的点到汇集(到达)该点)

    Code:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdbool.h>
      4 #include <malloc.h>
      5 #define maxn 10000
      6 #define maxm 50000
      7 
      8 struct node
      9 {
     10     long d;
     11     struct node *next;
     12 }*info[maxn+1];
     13 long x[maxm+1],y[maxm+1];
     14 long dfn[maxn+1],low[maxn+1],stack[maxn+1],num[maxn+1],ans[maxn+1],count=0,sum=0;
     15 bool vis[maxn+1],vis_stack[maxn+1],next[maxn+1];
     16 
     17 long min(long a,long b)
     18 {
     19     if (a>b)
     20         return b;
     21     else
     22         return a;
     23 }
     24 
     25 void tarjan(long d)
     26 {
     27     vis[d]=false;
     28     count++;
     29     stack[count]=d;
     30     dfn[d]=count;
     31     low[d]=count;
     32     struct node *p;
     33     long nd,pre;
     34     p=info[d];
     35     while (p)
     36     {
     37         nd=p->d;
     38         if (vis[nd]==true)
     39         {
     40             tarjan(nd);
     41             low[d]=min(low[d],low[nd]);
     42         }
     43         else if (vis_stack[nd]==true)
     44             low[d]=min(low[d],dfn[nd]);
     45         p=p->next;
     46     }
     47     pre=count;
     48     if (dfn[d]==low[d])
     49     {
     50         sum++;
     51         while (d!=stack[count])
     52         {
     53             num[stack[count]]=sum;
     54             vis_stack[stack[count]]=false;
     55             count--;
     56         }
     57         num[stack[count]]=sum;
     58         vis_stack[stack[count]]=false;
     59         count--;
     60         ans[sum]=pre-count;   //count+1~pre
     61     }
     62 }
     63 
     64 int main()
     65 {
     66     long i,n,m,d;
     67     struct node *p;
     68     scanf("%ld%ld",&n,&m);
     69 //    for (i=1;i<=n;i++)
     70 //        info[i]=NULL;
     71     for (i=1;i<=m;i++)
     72     {
     73         scanf("%ld%ld",&x[i],&y[i]);
     74         p=(struct node *) malloc (sizeof(struct node));
     75         p->d=y[i];
     76         p->next=info[x[i]];
     77         info[x[i]]=p;
     78     }
     79     for (i=1;i<=n;i++)
     80     {
     81         vis[i]=true;
     82         vis_stack[i]=true;
     83     }
     84     for (i=1;i<=n;i++)
     85         if (vis[i]==true)
     86             tarjan(i);
     87     for (i=1;i<=sum;i++)
     88         next[i]=false;
     89     for (i=1;i<=m;i++)
     90         if (num[x[i]]!=num[y[i]])
     91             next[num[x[i]]]=true;
     92     d=0;
     93     for (i=1;i<=sum;i++)
     94         if (next[i]==false)
     95         {
     96             if (d==0)
     97                 d=i;
     98             else
     99             {
    100                 d=-1;
    101                 break;
    102             }
    103         }
    104     if (d==-1)
    105         printf("0
    ");
    106     else
    107         printf("%ld
    ",ans[d]);
    108     return 0;
    109 }
  • 相关阅读:
    谈谈图片上传及canvas压缩的流程
    前端应该懂得初级Web分析指标
    java OPENCV 连通域, Imgproc.findContours 例子,参数说明
    [学习opencv]高斯、中值、均值、双边滤波
    Opencv 图像叠加 添加水印
    帧间提取水印
    opencv mat 转灰度图
    编写一条sql命令,sql删除没有中文的表
    使用JavaCV/OpenCV抓取并存储摄像头图像
    周掌柜
  • 原文地址:https://www.cnblogs.com/cmyg/p/6925874.html
Copyright © 2011-2022 走看看