zoukankan      html  css  js  c++  java
  • URAL 1742 Team building 强联通

    每个人到他认为最强的人连一条边。

    缩点后,入度为0的点是最小解,强联通分量是最大解。

    ---

    const int maxn=111100;
    const int maxm=210000;
    int n;
    struct Node {
        int to,next;
    } edges[maxm];
    int head[maxn],edge;
    void addedge(int u,int v) {
        edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    void prepare() {
        memset(head,-1,sizeof head);
        edge=0;
    }
    int a[maxn];
    int pre[maxn],lowlink[maxn],sccno[maxn],scc_cnt,dfs_clock;
    stack<int>stk;
    void dfs(int u) {
        pre[u]=lowlink[u]=++dfs_clock;
        stk.push(u);
        for (int i=head[u]; i!=-1; i=edges[i].next) {
            int v=edges[i].to;
            if (!pre[v]) {
                dfs(v);
                lowlink[u]=min(lowlink[u],lowlink[v]);
            } else if (!sccno[v]) {
                lowlink[u]=min(lowlink[u],pre[v]);
            }
        }
        if (lowlink[u]==pre[u]) {
            scc_cnt++;
            int x;
            do {
                x=stk.top();
                stk.pop();
                sccno[x]=scc_cnt;
            } while (x!=u);
        }
    }
    void find_scc(int n) {
        dfs_clock=scc_cnt=0;
        clr(sccno,0);
        clr(pre,0);
        while (!stk.empty()) stk.pop();
        REP_1(i,n) if (!pre[i]) dfs(i);
    }
    int num[maxn];
    int main() {
        memset(num,0,sizeof num);
        scanf("%d",&n);
        prepare();
        for (int i=1; i<=n; i++) {
            scanf("%d",&a[i]);
            addedge(i,a[i]);
        }
        find_scc(n);
        for (int i=1; i<=n; i++) {
            if (sccno[i]!=sccno[a[i]]) {
                num[sccno[a[i]]]++;
            }
        }
        int cnt=0;
        for (int i=0; i<scc_cnt; i++) {
            if (num[i]==0) cnt++;
        }
        printf("%d %d
    ",cnt,scc_cnt);
        return 0;
    }
    


    ---


  • 相关阅读:
    强化学习
    nginx环境准备
    全面解读PHP-数据结构
    全面解读PHP-数据库缓存
    跨域问题的解决方法
    使用 apt-get 清理
    怎样用 Bash 编程:逻辑操作符和 shell 扩展
    怎样用 Bash 编程:语法和工具
    使用 split 命令分割 Linux 文件,使用 cat 合并文件
    通过tar包解压安装docker
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681516.html
Copyright © 2011-2022 走看看