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

    题目链接

    https://ac.nowcoder.com/acm/problem/51269

    题意

    给你一张有向图,问最少加几条边使得图上的点属于同一个强连通分量。

    思路

    缩点后入度为0的点和出度为0的点取最大值, 特判缩点完只有一个点的情况。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 50;
    const int INF = 0x3f3f3f3f;
    struct node{
        int to, next;
    } edge[maxn];
    stack<int> s;
    int tot, sc, cnt;//sc为缩点后总点数
    int dfn[maxn], low[maxn];
    int scc[maxn], in[maxn], out[maxn];
    int head[maxn], vis[maxn];
    int sz[maxn];
    void add(int from, int to){
        edge[++cnt].to = to;edge[cnt].next = head[from];head[from] = cnt;
    }
    void ins(int u, int v){add(u, v); add(v, u);}
    void Tarjan(int u){
        dfn[u] = low[u] = ++tot;
        vis[u] = 1;
        s.push(u);
        for(int i = head[u];i != -1;i = edge[i].next){
            int v = edge[i].to;
            if(!dfn[v]){
                Tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(vis[v]) low[u] = min(low[u], dfn[v]);
        }
        if(dfn[u] == low[u]){
            sc++;
            int v;
            do{
                v = s.top();s.pop();
                scc[v] = sc;
                vis[v] = 0;
                sz[sc]++;
            }while(v != u);
        }
    }
    int main()
    {
        std::ios::sync_with_stdio(false);
        int n;
        cin >> n;
        memset(head, -1, sizeof(head));
        for(int i = 1;i <= n;i++){
            int x;
            while(cin >> x){
                if(!x) break;
                add(i, x);
            }
        }
        for(int i = 1;i <= n;i++){
            if(!dfn[i]) Tarjan(i);
        }
        for(int i = 1;i <= n;i++){
            for(int j = head[i]; j != -1;j = edge[j].next){
                int u = scc[i];
                int v = scc[edge[j].to];
                if(u != v) in[v]++, out[u]++;
            }
        }
        int cnt1 = 0, cnt2 = 0;
        for(int i = 1;i <= sc;i++){
            if(in[i] == 0) cnt1++;
            if(out[i] == 0)cnt2++;
        }
        if(sc == 1) cout << 1 << "
    " << 0 << endl;
        else cout << cnt1 << "
    " << max(cnt1, cnt2) << endl;
        return 0;
    }
    
    
  • 相关阅读:
    STM32CubeMX 使用
    Zookeeper集群搭建
    golang zookeeper监听事件报错
    git push 报错
    springboot使用postgresql模式下数据库表找不到
    不要在循环中访问数据库,这样会严重影响数据库性能
    SQL查询效率(Oracle)
    游标 数据集 效率比较
    oracle 视图
    INDEX SKIP SCAN 和 INDEX RANGE SCAN以及索引会失效
  • 原文地址:https://www.cnblogs.com/Carered/p/14287074.html
Copyright © 2011-2022 走看看