• Network of Schools poj 1236


    持续更新中。。。。

    Network of Schools

    http://poj.org/problem?id=1236

    给你一个有向图,有环的

    1.有个超级源点s,s最少连几个点时,可以从s走到图上任意一点

    2.最少添加几条边可以把图变成一个强连通分量

    ans1---缩点之后,入度为0 的点的个数

    ans2----缩点后,max(入度为0的点,出度为0的点),因为可以挨个连接,连的边转一圈,建议自己画一画

    记得特判一下

    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <set>
    #include<stack>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5+11;
    vector<int> G[maxn];
    void add(int x,int y){
       G[x].push_back(y);
    }
    
    int n;
    int ans,clor[maxn],df;
    int dfn[maxn],low[maxn];
    stack<int>s;
    
    
    int tarjan(int x){
        s.push(x);
        dfn[x] = low[x] = ++df;
        for (int i = 0; i < G[x].size();i++){
            int p = G[x][i];
            if(!dfn[p]){
                tarjan(p);
                low[x] = min(low[x], low[p]);
            }
            else if(!clor[p]){
                low[x] = min(low[x], dfn[p]);
            }
        }
    
        if(low[x] == dfn[x]){
            ans++;
            while(1){
                int a = s.top();
                s.pop();
                clor[a] = ans;
                if(a == x) break;
            }
        }
        return 0;
    }
    
    int in[maxn], ot[maxn];
    
    int main(){
        cin >> n;
        int x;
        for (int i = 1; i <= n;i++){
          
            while(1){
                cin >> x;
                if(x == 0) break;
                add(i, x);
            }
        }
        for (int i = 1; i <= n;i++){
            if(dfn[i] == 0){
                tarjan(i);
            }
        }
        for (int i = 1; i <= n;i++){
            for (int j = 0; j < G[i].size();j++){
                int p = G[i][j];
                int x = clor[i];
                int y = clor[p];
                if(x != y){
                    //x---->y
                    in[y]++;
                    ot[x]++;
                }
            }
        }
    
        int a = 0, b = 0;
        for (int i = 1; i <= ans; i++){
            if(in[i] == 0) a++;
            if(ot[i] == 0) b++;
        }
        if(ans == 1){
            cout << 1 << endl;
            cout << 0 << endl;
            return 0;
        }
    
        cout << a << endl;
        cout << max(a,b) << endl;
        return 0;
    }
    

      

  • 相关阅读:
    iOS7.0后隐藏状态栏(UIStatusBar)
    UITableView
    UIScrollView
    [IOS]edgesForExtendedLayout、automaticallyAdjustsScrollViewInsets
    UISearchController
    App开发流程之通用宏定义及头文件
    App开发流程之Xcode配置和本地化
    App开发流程之源代码Git管理
    App开发流程之增加预编译头文件
    App开发流程之配置Info.plist文件
  • 原文地址:https://www.cnblogs.com/lesning/p/14073869.html
Copyright © 2020-2023  润新知