zoukankan      html  css  js  c++  java
  • P2746 [USACO5.3]校园网Network of Schools 强连通

      

    题目描述

    一些学校连入一个电脑网络。那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”)。注意即使 B 在 A 学校的分发列表中, A 也不一定在 B 学校的列表中。

    你要写一个程序计算,根据协议,为了让网络中所有的学校都用上新软件,必须接受新软件副本的最少学校数目(子任务 A)。更进一步,我们想要确定通过给任意一个学校发送新软件,这个软件就会分发到网络中的所有学校。为了完成这个任务,我们可能必须扩展接收学校列表,使其加入新成员。计算最少需要增加几个扩展,使得不论我们给哪个学校发送新软件,它都会到达其余所有的学校(子任务 B)。一个扩展就是在一个学校的接收学校列表中引入一个新成员。

    输入输出格式

    输入格式:

    输入文件的第一行包括一个整数 N:网络中的学校数目(2 <= N <= 100)。学校用前 N 个正整数标识。

    接下来 N 行中每行都表示一个接收学校列表(分发列表)。第 i+1 行包括学校 i 的接收学校的标识符。每个列表用 0 结束。空列表只用一个 0 表示。

    输出格式:

    你的程序应该在输出文件中输出两行。

    第一行应该包括一个正整数:子任务 A 的解。

    第二行应该包括子任务 B 的解。

    输入输出样例

    输入样例#1: 复制
    5
    2 4 3 0
    4 5 0
    0
    0
    1 0
    输出样例#1: 复制
    1
    2

    1.求最少给多少学校发软件能遍历所有学校 入度的值即可
    2.最少加几条边使得整个图强连通 和之前做的一题很像

    还有就是注意cnt为1的情况要特判
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=500+5;
    const int M=N*N;
    int head[M],pos;
    struct Edge
    {
        int nex,to,v;
    }edge[M];
    struct node
    {
        int s,e;
    }s[M];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    int tot,ind,cnt,Stack[N],dfn[N],low[N],vis[N],belong[N],in[N],out[N];
    int n,m;
    void init()
    {
        tot=ind=cnt=pos=0;
        CLR(in,0);
        CLR(out,0);
        CLR(Stack,0);
        CLR(head,0);
        CLR(vis,0);
        CLR(dfn,0);
        CLR(low,0);
    }
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tot;
        Stack[++ind]=x;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(!dfn[v])
            {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(vis[v])
                low[x]=min(low[x],low[v]);
        }
        if(dfn[x]==low[x])
        {
            cnt++;int v;
            do
            {
                v=Stack[ind--];
                vis[v]=0;
                belong[v]=cnt;
            }
            while(x!=v);
        }
    }
    
    int main()
    {
       int n;
       RI(n);
       rep(i,1,n)
       {
           int x;
           while(RI(x),x)
           {
               add(i,x);
           }
       }
       rep(i,1,n)
       if(!dfn[i])
        tarjan(i);
    
       rep(i,1,n)
       {
           int u=belong[i];
           for(int j=head[i];j;j=edge[j].nex)
           {
               int v=belong[edge[j].to];
               if(u!=v)
               in[v]++,out[u]++;
           }
       }
       int q=0,w=0;
       rep(i,1,cnt)
       {
           if(!in[i])q++;
           if(!out[i])w++;
       }
    
       if(cnt==1)
        cout<<1<<endl<<0<<endl;
       else
       cout<<q<<endl<<max(q,w);
        return 0;
    }
    View Code






  • 相关阅读:
    img标签与span一起使用不在同一条线上
    媒体查询
    section标签实现文字滚动
    js活jQuery实现动态添加、移除css/js文件
    页面中动态改变浏览器标题
    css清浮动与动态计算元素宽度
    js实现60s倒计时效果
    js与es6中获取时间戳
    JavaScript中实现小数点后保留2位
    GMT时间转换
  • 原文地址:https://www.cnblogs.com/bxd123/p/10801622.html
Copyright © 2011-2022 走看看