zoukankan      html  css  js  c++  java
  • nyoj 120 校园网络

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=120

    思路:先将原图强连通缩点为新图,统计新图中入度,出度为0的点的个数,两者取最大值即为答案。

    代码如下:

    #include "stdio.h"
    #include "string.h"
    #include "stack"
    #include "vector"
    using namespace std;
    
    #define N 105
    #define M 10005
    
    struct node
    {
        int x,y;
        int next;
    }edge[2*M];
    int idx,head[N];
    void Init(){ idx=0; memset(head,-1,sizeof(head)); }
    inline int MIN(int a,int b){ return a<b?a:b; }
    inline int MAX(int a,int b){ return a>b?a:b; }
    void Add(int x,int y)
    {
        edge[idx].x=x;
        edge[idx].y=y;
        edge[idx].next=head[x];
        head[x]=idx++;
    }
    
    bool vis[N];
    int dfn[N],low[N];
    int dfs_clock;
    int countt;
    int belong[N];
    stack<int> q;
    
    
    void DFS(int x)   //强连通缩点算法
    {
        int i,y;
        q.push(x);
        vis[x] = true;
        dfn[x] = low[x] = ++dfs_clock;
        for(i=head[x]; i!=-1; i=edge[i].next)
        {
            y = edge[i].y;
            if(!dfn[y])
            {
                DFS(y);
                low[x] = MIN(low[x],low[y]);
            }
            else if(vis[y])
                low[x] = MIN(dfn[y],low[x]);
        }
        if(low[x]==dfn[x])
        {
            int temp;
            countt++;
            while(1)
            {
                temp = q.top();
                q.pop();
                belong[temp] = countt;
                vis[temp] = false;
                if(temp==x) break;
            }
        }
    }
    
    int ru_du[N],chu_du[N];
    
    int Solve(int n)
    {
        int i;
        int x,y;
        dfs_clock = countt = 0;
        memset(dfn,0,sizeof(dfn));
        memset(vis,false,sizeof(vis));
        memset(belong,0,sizeof(belong));
        for(i=1; i<=n; ++i)
        {
            if(!dfn[i])
                DFS(i);
        }
        if(countt==2) return 0;  //该图原本就是强连通图,return 0;
        memset(ru_du,0,sizeof(ru_du));
        memset(chu_du,0,sizeof(chu_du));
        for(i=0; i<idx; ++i)
        {
            x = belong[edge[i].x];
            y = belong[edge[i].y];
            if(x!=y)  //统计入度,出度
            {
                chu_du[x]++;
                ru_du[y]++;
            }
        }
        int ru_0=0,chu_0=0;
        for(i=1; i<countt; ++i)
        {
            if(ru_du[i]==0) ru_0++;
            if(chu_du[i]==0) chu_0++;
        }
        int ans = MAX(ru_0,chu_0); //return 入度,出度最大的那个数
        return ans;
    }
    
    int main()
    {
        int T;
        int n;
        int i,k;
        scanf("%d",&T);
        while(T--)
        {
            Init();
            scanf("%d",&n);
            for(i=1; i<=n; ++i)
            {
                while(scanf("%d",&k),k)
                    Add(i,k);
            }
            printf("%d
    ",Solve(n));
        }
        return 0;
    }
    


  • 相关阅读:
    怎样建设一个比较好的地方性商业门户网站
    地方门户网站如何推广
    【转】地方门户网站:地区细分领域的蓝海市场
    【转】测试人员可能会遇到的问题
    【转】工作反思-跳槽篇
    简单验证码识别 tessnet2
    log4net使用详解
    java理论基础学习三
    java理论基础学习二
    java理论基础学习一
  • 原文地址:https://www.cnblogs.com/ruo-yu/p/4411954.html
Copyright © 2011-2022 走看看