zoukankan      html  css  js  c++  java
  • kuangbin专题-连通图A

    这道题的意思是就是

    问题

    1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。

    2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

     其实问题1就是问,这个图的支配集有多少???解决这个问题非常简单,把图缩点后,找到有多少个入度为0的点,就是支配集。一个支配内,所有点可能不是强连通的,但是都可以通过这个点到达。

      而问题二其实更加简单,我们只需要把入读为0的点和出度为0的点的数目取一个最大值即可,至于问什么,很简单,我们可以把出度为0的点连接到入度为0的点上面去,这样就保证图的强连通性质。其实这就是求一个图的补图。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    const int N = 100010,M=1000010;
    int ver[M],Next[M],head[N],dfn[N],low[N];
    int sta[N],ins[N],c[N],in_deg[N],out_deg[N];
    int n,m,tot,num,top,cnt;
    void add(int x,int y)
    {
        ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
    }
    void tarjan(int x)
    {
        dfn[x]=low[x]=++num;//序列号+1
        sta[++top]=x,ins[x]=1;//入栈,并标记在栈内
        for (int i=head[x]; i; i=Next[i])  //开始访问
            if(!dfn[ver[i]]) //如果没有被处理过
            {
                tarjan(ver[i]);//DFS
                low[x]=min(low[x],low[ver[i]]);
    //递归出来,比较谁是谁的儿子/父亲,就是树的对应关系,涉及到强连通分量子树最小根的事情
            }
            else if (ins[ver[i]])
                low[x]=min(low[x],dfn[ver[i]]);
    //比较谁是谁的儿子/父亲。就是链接对应关系
            if (dfn[x] == low[x])//发现是整个强连通分量的子树里面的最小根。
            {
                cnt++;
                int y;
                do
                {
                    y=sta[top--],ins[y]=0;
                    c[y]=cnt;
                    //scc[cnt].push_back(y);
                }
                while(x!=y);
            }
    }
    void solve(int n)
    {
        for (int i=1; i<=n; i++)
        {
            if (!dfn[i])
            {
                tarjan(i);
            }
        }
        if (cnt==1)
        {
            printf("1
    0
    ");
            return;
        }
        for (int u=1; u<=n; ++u)
        {
            for (int j=head[u]; j; j=Next[j])
            {
                int v=ver[j];
                if (c[u]==c[v])
                {
                    continue;
                }
                out_deg[c[u]]++;
                in_deg[c[v]]++;
            }
        }
        int a,b;
        a=0;
        b=0;
        for (int i=1; i<=cnt; i++)
        {
            if (in_deg[i]==0)
            {
                a++;
            }
            else if (out_deg[i]==0)
            {
                b++;
            }
        }
        printf("%d
    ",a);
        printf("%d
    ",max(a,b));
    
    }
    void init()
    {
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(head,0,sizeof(head));
        memset(in_deg,0,sizeof(in_deg));
        memset(out_deg,0,sizeof(out_deg));
        memset(ins,0,sizeof(ins));
        top=0;
        tot=0;
        cnt=0;
        num=0;
    }
    int main()
    {
        int  tmp;
        while(~scanf("%d",&n))
        {
            init();
            for (int i=1; i<=n; i++)
            {
                while(scanf("%d",&tmp)&&tmp)
                {
                    add(i,tmp);
                }
            }
            solve(n);
        }
        return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    CodeForce VKcup A
    CNN卷积神经网络
    神经网络
    我的机器学习之路
    [OPENCV] 第一个程序 识别颜色
    Android 登录界面与首页的设计
    go web的基本原理
    Go语言标准库之http/template
    吞吐量(TPS)、QPS、并发数、响应时间(RT)概念
    数据库恢复技术
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11222329.html
Copyright © 2011-2022 走看看