zoukankan      html  css  js  c++  java
  • POJ1236 Network of Schools

    gate

    用时:大概60min
    睡前随便水一发博客,摸了

    有向图,一个点向其他点连边(传递信息)。
    问:1.至少选多少点作为源点,使所有点都能收到信息。2.至少连多少边,使任选一点作为源点,都能使所有点收到消息。
    显然每个强联通分量内的点可以互相到达,所以先缩点。
    1的答案即为入度为0的点的个数。
    2即要使每一点都有入度和出度,答案为入度和出度为0的点的较大值。
    注意特判强连通图的情况,因为至少要选一个点。输入1,0即可。

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #define Mogeko qwq
    using namespace std;
    
    const int maxn = 1e5+10;
    int n,m,x[maxn],y[maxn],inn[maxn],out[maxn],ans1,ans2;
    int head[maxn],to[maxn],nxt[maxn],cnt;
    int dfn[maxn],low[maxn],sta[maxn],col[maxn],top,now,num;
    bool insta[maxn];
    
    int read(){
        int x = 0,f = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9'){
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while('0' <= ch && ch <= '9'){
            x = x*10 + ch-'0';
            ch = getchar();
        }
        return x*f;
    }
    
    void add(int x,int y){
        to[++cnt] = y;
        nxt[cnt] = head[x];
        head[x] = cnt;
    }
    
    void clear(){
        memset(head,0,sizeof(head));
        memset(to,0,sizeof(to));
        memset(nxt,0,sizeof(nxt));
    }
    
    void tarjan(int u){
        dfn[u] = low[u] = ++now;
        sta[++top] = u;
        insta[u] = true;
        for(int i = head[u];i;i = nxt[i]){
            int v = to[i];
            if(!dfn[v]){
                tarjan(v);
                low[u] = min(low[u],low[v]);
            }
            else if(insta[v])
                low[u] = min(low[u],dfn[v]);
        }
        if(low[u] == dfn[u]){
            col[u] = ++num;
            insta[u] = false;
            while(sta[top] != u){
                int v = sta[top--];
                col[v] = num;
                insta[v] = false;
            }
            top--;
        } 
    }
    
    int main(){
        n = read();
        for(int i = 1;i <= n;i++)
            while(1){
                int j = read();
                if(!j) break;
                add(i,j);
                m++;
                x[m] = i, y[m] = j;
            }
        for(int i = 1;i <= n;i++)
            if(!dfn[i]) tarjan(i);
        clear();
        for(int i = 1;i <= m;i++)
            if(col[x[i]] != col[y[i]]){
                out[col[x[i]]]++;
                inn[col[y[i]]]++;
            }
        for(int i = 1;i <= num;i++){
            if(!inn[i]) ans1++;
            if(!out[i]) ans2++;
        }
        if(num == 1) printf("1
    0
    ");
        else printf("%d
    %d
    ",ans1,max(ans1,ans2));
        return 0;
    }
    
  • 相关阅读:
    黄聪:VirtualBox 安装ghost版windows XP
    黄聪:Delphi 关键字详解[整理于 "橙子" 的帖子]
    黄聪:全局变量 HInstance 到底是在什么时候赋值的?
    黄聪:演示 Rect、Bounds 生成 TRect 的区别
    黄聪:C#操作合并多个Word文档
    黄聪:C# .Net三层架构[转]
    黄聪:遗传算法实现自动组卷、随机抽题
    黄聪:SQL转换日期字段的问题——SQL中CONVERT转化函数的用法[转]
    黄聪:System 提供的编译期函数
    黄聪:语言字符集
  • 原文地址:https://www.cnblogs.com/mogeko/p/13210935.html
Copyright © 2011-2022 走看看