zoukankan      html  css  js  c++  java
  • poj 1236 Network of Schools 强连通分量 (添加几条边可以使整个图变成强连通图)

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

    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<string.h>
    #include<stack>
    using namespace std;
    vector <int > g[1002];
    int pre[1002],low[1002],lt_num,c,scc_num[1002],scc,in0[1002],out0[1002],n,a,b;
    
    stack <int >s;
    void dfs(int u)
    {
        int i,v;
        pre[u]=low[u]=c++;
        s.push (u);
        for(i=0;i<g[u].size ();i++)
        {
            v=g[u][i];
            if(!pre[v])//!scc_num[v]
            {
                dfs(v);
                if(low[v]<low[u])
                    low[u]=low[v];
            }
            else if(low[v]<low[u]&&!scc_num[v])
                low[u]=low[v];
        }
        if(low[u]==pre[u])   //是该连通分量的 第一个点
        {
            scc++;
            while(1)
            {
                int t=s.top ();s.pop ();
                scc_num[t]=scc;             //scc_num[t]是第scc个强连通分量;
                if(t==u)
                    break;
            }
    
        }
    
    }
    
    int solve()
    {
        if(scc==1)
            return 0;
        int i,j,v;
        a=0,b=0;
        for(i=0;i<=scc;i++)
            in0[i]=out0[i]=0;
        for(i=1;i<=n;i++)
            for(j=0;j<g[i].size ();j++)
            {
                v=g[i][j];
                if(scc_num[i]!=scc_num[v])
                     out0[scc_num[i]]++,in0[scc_num[v]]++;
            }
            for(i=1;i<=scc;i++)
            {
                if(!in0[i])
                    a++;
                if(!out0[i])
                    b++;
            }
            return a>b?a:b;
    }
    int main()
    {
        int i,q;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=1;i<=n;i++)
                g[i].clear ();
            for(i=1;i<=n;i++)
            {
                while(scanf("%d",&q))
                {
                    if(q==0)
                        break;
                    g[i].push_back (q);
                }
            }
            c=1; scc=0;lt_num=0;
            memset(pre,0,sizeof(pre));
            
            memset(scc_num,0,sizeof(scc_num));
            for(i=1;i<=n;i++)
                if(!pre[i])
                {
                    lt_num++;
                    dfs(i);
                }
                if(scc==1)
    { printf(
    "1 0 "); continue; } int as=solve(); printf("%d ",a); printf("%d ",as); while(!s.empty ()) s.pop (); } return 0; }
  • 相关阅读:
    git命令总结
    Junit
    zookeeper--概述
    NIO与Socket
    分区分表
    ThreadLocal
    垃圾收集器
    垃圾收集算法
    主从复制
    Redis--集群
  • 原文地址:https://www.cnblogs.com/assult/p/3231361.html
Copyright © 2011-2022 走看看