• OJ 1234 校园网络


         
     
    From easthong
    校园网络
     
         
         
      描述 Description  
      一些学校连入一个电脑网络。那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”)。注意如果 B 在 A 学校的分发列表中,那么 A 不必也在 B 学校的列表中。

    你要写一个程序计算,根据协议,为了让网络中所有的学校都用上新软件,必须接受新软件副本的最少学校数目(子任务 A)。更进一步,我们想要确定通过给任意一个学校发送新软件,这个软件就会分发到网络中的所有学校。为了完成这个任务,我们可能必须扩展接收学校列表,使其加入新成员。计算最少需要增加几个扩展,使得不论我们给哪个学校发送新软件,它都会到达其余所有的学校(子任务 B)。一个扩展就是在一个学校的接收学校列表中引入一个新成员。
         
         
      输入格式 Input Format  
      第一行包括一个整数 N:网络中的学校数目(2 <= N <= 100)。学校用前 N 个正整数标识。接下来 N 行中每行都表示一个接收学校列表(分发列表)。第 i+1 行包括学校 i 的接收学校的标识符。每个列表用 0 结束。空列表只用一个 0 表示。
         
         
      输出格式 Output Format  
      第一行应该包括一个正整数:子任务 A 的解。第二行应该包括子任务 B 的解。
         
         
      样例输入 Sample Input  
     
         
         
      样例输出 Sample Output  
     
         
         
      时间限制 Time Limitation  
      1s
         
         
      注释 Hint  
       
         
         
      来源 Source  
      usaco 5.3.3

    这道题有两问

    第一问很简单,先tarjin缩一下点,然后找出所有入度为0的点,那么这些点是必须要副本的,其他的点一定可以有这些点到达,所以答案就是所有入度为0的点

    第二问,有一个小结论,就是一个有向图我们只需要最多连max(入度为0的点的个数,初度为0的点的个数)条边,那么个图就可以成为强连通的,即从任意一个点可以到达另外所有点,但当只有一个强连通分量的时候要输出0而不是1

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int MAXN=1e4+10;
    namespace zhangenming{
        struct node{
              int x,y,next;
        }e[MAXN];
        int linkk[MAXN],len=0,n;
        inline void insert(int xx,int yy){
             e[++len].y=yy;e[len].x=xx;e[len].next=linkk[xx];linkk[xx]=len;
        }
       void init(){
           n=read();
           for(int i=1;i<=n;i++){
            int xx=read(); 
               while(xx){
                   insert(i,xx);
                xx=read();
               }    
           }
        }
        int vis[MAXN],stark[MAXN],ine[MAXN],cntt[MAXN]={},tot=0,top=0,cnt[MAXN]={},dfn[MAXN]={},low[MAXN],dfs_clock=0;
        inline void tarjin(int st){
            //cout<<st<<endl;
            dfn[st]=low[st]=++dfs_clock;vis[st]=1;
            stark[++top]=st;
            for(int i=linkk[st];i;i=e[i].next){
                if(!dfn[e[i].y]){
                    //cout<<e[i].y<<endl;
                    tarjin(e[i].y);
                    low[st]=min(low[st],low[e[i].y]);
                }
                else if(vis[e[i].y]) low[st]=min(low[st],dfn[e[i].y]);
            }
            if(low[st]==dfn[st]){
                tot++;
                int k;
                do{
                    k=stark[top--];
                    ine[k]=tot;
                    vis[k]=0;
                }while(k!=st);
            }
        }
        void solve(){
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=n;i++){
                if(!ine[i]) tarjin(i);
            }
            for(int i=1;i<=len;i++){
                int xx=e[i].x;int yy=e[i].y;
                if(ine[xx]==ine[yy]) continue;
                cnt[ine[yy]]++;
                cntt[ine[xx]]++;
            }
            int sum1=0;int sum2=0;
            for(int i=1;i<=tot;i++){
                if(!cnt[i]) sum1++;
                if(!cntt[i]) sum2++;
            }
            cout<<sum1<<endl;
            if(tot!=1) cout<<max(sum1,sum2)<<endl;
            else cout<<0<<endl;
        }
    }
    int main(){
        using namespace zhangenming;
        init();
        solve();
        return 0;
    }
    

      

  • 相关阅读:
    O(n^2)的排序方法
    99乘法表
    excel 转 csv
    批量关闭 excel
    tomcat 加入服务
    文件打包 zip
    字符串转换
    List数组种删除数据
    mybatis 批量上传
    sql server 查询表字段及类型
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7881520.html
Copyright © 2020-2023  润新知