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;
    }
    
    
  • 相关阅读:
    INV*更新物料信息
    WPF设置样式的几种方式
    使用InternetGetConnectedState判断本地网络状态(C#举例)
    WinInet API详解
    WPF导航总结
    WPF中的命令与命令绑定导航
    WPF依赖属性相关博客导航
    关于WPF自定义控件(导航)
    WPF送走控件的focus方法
    MvvmLight学习篇—— Mvvm Light Toolkit for wpf/silverlight系列(导航)
  • 原文地址:https://www.cnblogs.com/Carered/p/14287074.html
Copyright © 2011-2022 走看看