• P2812 校园网络【[USACO]Network of Schools加强版】


    题目背景

    浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件。但是由于他们脑力劳动过多导致全身无力身体被♂掏♂空,他们来找你帮助他们。

    题目描述

    共有n所学校(n<=10000)已知他们实现设计好的网络共m条线路,为了保证高速,网络是单向的。现在请你告诉他们至少选几所学校作为共享软件的母机母鸡,能使每所学校都可以用上。再告诉他们至少要添加几条线路能使任意一所学校作为母机母鸡都可以使别的学校使用上软件。

    输入输出格式

    输入格式:

    第一行一个整数n。

    接下来n行每行有若干个整数,用空格空格隔开。

    第i-1行的非零整数x,表示从i到x有一条线路。以0作为结束标志。

    输出格式:

    第一行一个整数表示问题1的答案。

    第二行回答问题2.

    输入输出样例

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

    说明

    POJ原题。数据扩大了100倍。

    边数 ≤5000000

    Solution:

      本题zyys(吐槽:数据加强?我先做的加强版,蒯了AC代码去普通版WA了,原因不说了)。

      思路:tarjan缩点。

      对于第1问,我们求出缩点后的各连通图中入度为0的点的个数就行了。

      对于第2问,等价于使得缩点后的各连通图中的每个点的出入度至少为1,不必考虑具体建图的过程(实际是出度为0连向入度为0,构成环),反正答案就是$max$(入度为0个数,出度为0个数)。

    代码:

    /*Code by 520 -- 8.21*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long 
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=20005,M=5000005;
    struct node{
        int u,v;
    }e[M];
    int n,m,tot,dfn[N],low[N];
    int to[M],net[M],h[N],cnt,la;
    int stk[N],top,scc,bl[N],cd[N],rd[N];
    int ans1,ans2;
    bool ins[N];
    
    int gi(){
        int a=0;char x=getchar();
        while(x<'0'||x>'9')x=getchar();
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+(x^48),x=getchar();
        return a;
    }
    
    il void add(int u,int v){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt;}
    
    void tarjan(int u){
        dfn[u]=low[u]=++tot,stk[++top]=u,ins[u]=1;
        for(RE int i=h[u];i;i=net[i]){
            int v=to[i];
            if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
            else if(ins[v]) low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u]){
            scc++;
            while(stk[top+1]!=u)
                bl[stk[top]]=scc,ins[stk[top--]]=0;
        }
    }
    
    il void init(){
        n=gi();
        RE int v;
        For(i,1,n)
            while(1){
                v=gi();
                if(!v)break;
                add(i,v),e[++la].u=i,e[la].v=v;
            }
        For(i,1,n) if(!dfn[i]) tarjan(i);
        memset(h,0,sizeof(h)),cnt=0;
        if(scc==1)cout<<1<<'
    '<<0,exit(0);
        For(i,1,la) if(bl[e[i].u]!=bl[e[i].v]) cd[bl[e[i].u]]++,rd[bl[e[i].v]]++;
        For(i,1,scc) {
            if(!rd[i]) ans1++;
            if(!cd[i]) ans2++;
        }
        printf("%d
    %d",ans1,max(ans1,ans2));
    }
    
    int main(){
        init();
        return 0;
    }
  • 相关阅读:
    hdu1425
    iOS 纯代码跳转到Xib界面和Storyboard界面
    iOS 获取当前app的 App Store 版本号
    iOS 延时方法,定时器。等待一段时间在执行
    iOS获取当前app的名称和版本号及其他信息(持续维护)
    iOS 截取字符串(持续更新)截取、匹配、分隔
    iOS 屏幕大小尺寸,分辨率,代码获取屏幕大小(持续维护添加)
    iOS NSString只保留字符串中的数字
    iOS NSlog打印数据不完全,xcode处理办法
    iOS Xcode 10.3 xib:-1:未能找到或创建描述的执行上下文“<IBCocoaTouchPlatformToolDescript
  • 原文地址:https://www.cnblogs.com/five20/p/9515555.html
Copyright © 2020-2023  润新知