zoukankan      html  css  js  c++  java
  • HAOI2006 (洛谷P2341)受欢迎的牛 题解

    HAOI2006 (洛谷P2341)受欢迎的牛 题解

    题目描述

    友情链接原题

    每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

    牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

    欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

    算出有多少头奶牛可以当明星。

    输入输出格式

    输入格式:

    第一行:两个用空格分开的整数:N和M

    第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B

    输出格式:

    第一行:单独一个整数,表示明星奶牛的数量

    输入输出样例

    输入样例#1:

    3 3
    1 2
    2 1
    2 3
    

    输出样例#1:

    1
    

    说明

    只有 3 号奶牛可以做明星

    【数据范围】

    10%的数据N<=20, M<=50

    30%的数据N<=1000,M<=20000

    70%的数据N<=5000,M<=50000

    100%的数据N<=10000,M<=50000

    题目分析

    这是一道强连通分量的题

    首先把样例拿来画一下(解决图论题目常规操作),得到如下的图:

    样例

    我们可以发现一号和二号可以构成一个强连通分量,然后就会想到tarjan缩点。。把一号和二号缩点后,可以得到如下的图:

    2

    我们推论:缩点后出度为零的点为明星牛(假如出度为零的点是一个强连通分量的缩点,那么这个强连通分量中的所有牛都是明星牛)这个其实很好证,假如明星牛的出度不为0,它就会和其他点构成一个强连通分量,那么就是缩点不彻底,而我们讨论的是完全缩点后的情况。

    我们在举一个例子

    3

    缩点后的图是这样的

    4

    这两个点都是出度为0,但是我们发现并没有明星牛。原因是有两个点出度为零。所以推论应该改为:缩点后唯一的出度为0的点是明星牛,这样也可以避免掉单独的点带来的影响。

    假如这整个图就是一个强连通图,那么每一头牛都是明星牛(缩点后只有一个点,仍然满足推论)。

    然后这个题就简单了,算是裸的tarjan。

    附上标程

    #include<bits/stdc++.h>
    #define maxn 1000000
    using namespace std;
    int Next[maxn],a=0,F[maxn],Head[maxn];
    int cmpi[maxn],out[maxn],E[maxn],cmp[maxn],s[maxn];
    int dfn[maxn],low[maxn],top=0,cmpid=0,tim=0;
    bool V[maxn],D[maxn];
    void ins(int x,int y,int i)
    {
        E[i]=y;
        Next[i]=Head[x];
        Head[x]=i;
    }//链式前向星
    int find()
    {
        int ans=0;
        for(int i=1;i<=a;i++)
        {
            for(int p=Head[F[i]];p;p=Next[p])//列举这个点的所有邻接点
            {
                if(!D[E[p]])ans++;//如果这个点的邻接点不和他在一个强联通分量的话,那么我们就发现他所在的分量有了出度
            }
        }
        return ans;
    }//找一组强连通分量的出度
    void tarjan(int u)
    {
        dfn[u]=low[u]=++tim;
        s[++top]=u;
        V[u]=true;
        for(int p=Head[u];p;p=Next[p])
        {
            int y=E[p];
            if(!dfn[y])
            {
                tarjan(y);
                low[u]=min(low[y],low[u]);
            }
            else
            {
                if(V[y])low[u]=min(low[u],dfn[y]);
            }
        }
        if(dfn[u]==low[u])
        {
            int y;
            cmpid++;
            do
            {
                y=s[top--];
                V[y]=false;
                F[++a]=y;//将这个点存入暂时数组
                D[y]=true;
                cmpi[cmpid]++;
            }while(y!=u);
            cmp[cmpid]=find();//cmp存储他的出度
            a=0;
            memset(D,false,sizeof(D));//D数组表示这个点在不在这个强连通分量
        }
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            ins(a,b,i);
        }
        for(int i=1;i<=n;i++)
           if(!dfn[i])tarjan(i);
        int c=0,ans;
        for(int i=1;i<=cmpid;i++)
          if(!cmp[i])c++,ans=i;//检查图是否连通
        if(c==1)printf("%d",cmpi[ans]);//输出
        else printf("0");
        return 0;
    } 
    
  • 相关阅读:
    eclipse plugin development -menu
    Eclipse 插件开发 -- 深入理解菜单(Menu)功能及其扩展点( FROM IBM)
    eclipse core expression usage
    eclipse preference plugin development store and get
    eclipse default handler IHandler interface “the chosen operation is not enabled”
    sublime text 3-right click context menu
    SoapUI Pro Project Solution Collection-Custom project and setup
    SoapUI Pro Project Solution Collection-XML assert
    Cordova Ionic AngularJS
    centos
  • 原文地址:https://www.cnblogs.com/opbnbjs/p/9388032.html
Copyright © 2011-2022 走看看