zoukankan      html  css  js  c++  java
  • POJ 1236 Network of Schools

    之前对Kosaraju_Algorithm理解有误,现在彻底明白了。

    Kosaraju_Algorithm:

    •  step1:对原图G进行深度优先遍历,记录每个节点的离开时间。形成了一个森林(很多树)
    •  step2:选择具有最晚离开时间的顶点,对反图GT进行遍历,删除能够遍历到的顶点,这些顶点构成一个强连通分量。
    •  step3:如果还有顶点没有删除,继续step2,否则算法结束。
     
    对于这个题目,第一问的答案就是缩点之后入度为0的节点的个数,第二问就是max(入度为0的结点个数,出入为0的结点个数)
    如果本来就只有一个强连通分量,那么输出1 0就可以了。
     
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const int maxn=105;
    int Dfn[maxn],U[100000],V[100000],Belong[maxn];
    int In[maxn],Out[maxn],flag[maxn];
    struct Point
    {
        int id,dfn;
    } point[maxn];
    vector<int>G[maxn];
    vector<int>FG[maxn];
    int N,Tot;
    int Sum,Block,in,out;
    
    void init()
    {
        for(int i=0; i<maxn; i++) G[i].clear();
        for(int i=0; i<maxn; i++) FG[i].clear();
        memset(Dfn,0,sizeof Dfn);
        memset(In,0,sizeof In);
        memset(Out,0,sizeof Out);
        memset(flag,0,sizeof flag);
        Tot=0;//时间戳
        Sum=0;//边的数目
        Block=0;//强连通分量的数目
        in=0;//统计入度为0的点的数目
        out=0;//统计出度为0的点的数目
    }
    
    bool cmp(const Point&a,const Point&b)
    {
        return a.dfn>b.dfn;
    }
    
    void Dfs(int now)
    {
        flag[now]=1;
        for(int i=0; i<G[now].size(); i++)
            if(!flag[G[now][i]])
                Dfs(G[now][i]);
        Tot++;
        Dfn[now]=Tot;
    }
    
    void dfs(int now)
    {
        Belong[now]=Block;
        for(int i=0; i<FG[now].size(); i++)
            if(!Belong[FG[now][i]])
                dfs(FG[now][i]);
    }
    
    int main()
    {
        while(~scanf("%d",&N))
        {
            init();
            for(int i=1; i<=N; i++)
            {
                while(1)
                {
                    int v;
                    scanf("%d",&v);
                    if(!v) break;
                    Sum++;
                    U[Sum]=i;
                    V[Sum]=v;
                    G[i].push_back(v);
                    FG[v].push_back(i);
                }
            }
            for (int i = 1; i <= N; i++) if (!flag[i]) Dfs(i);
            for(int i=0; i<N; i++)
                point[i].id=i+1, point[i].dfn=Dfn[i+1];
            sort(point,point+N,cmp);
            for(int i=0; i<N; i++)
                if(!Belong[point[i].id])
                    Block++,dfs(point[i].id);
            for(int i=1; i<=Sum; i++)
                if(Belong[U[i]]!=Belong[V[i]])
                    Out[Belong[U[i]]]++,In[Belong[V[i]]]++;
            for(int i=1; i<=Block; i++)
            {
                if(!In[i]) in++;
                if(!Out[i]) out++;
            }
            if(Block==1) printf("1
    0
    ");
            else printf("%d
    %d
    ",in,max(in,out));
        }
        return 0;
    }
  • 相关阅读:
    js 实现加入收藏/加入首页功能
    js 获取网页宽/高度
    js 飞机大战
    js 实现分享功能
    前端开发的工具,库和资源总结
    网站更新后客户端缓存问题
    js 实现图片无限横向滚动效果
    js 实现 文字打印效果
    js 构造函数创建钟表
    Css3 实现关键帧动画
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4766222.html
Copyright © 2011-2022 走看看