• POj 2186 Popular Cows[连通分量]


    题目大意:给出N头牛,有M种关系u, v。代表u牛崇拜v牛。要求找出有多少头牛被所有牛崇拜着
    题目链接:http://poj.org/problem?id=2186
    解题思路:
    1>求出强连通分量,标记每头牛属于哪个分量内
    2>进行缩点,计算连通分量的个数x,给出的M组关系重新构图。u,v若属不于一个连通分量内out[belong[u]]++;
    3>统计x个连通分量出度。如果超过1个的连通分量出度为0,证明两群牛互不崇拜;
       如果等于1 答案就是该分量中牛的个数.

    代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    #define N 10005
    #define M 50005
    struct Edge
    {
        int v, next;
    }edge[M];
    
    int node[N], stack[N], instack[N], dfn[N], out[N];
    int low[N], belong[N], index, cnt_edge, n, m, cnt_tar, top;
    int ee[M][2];
    
    void add_Edge(int u, int v)
    {
        edge[cnt_edge].next=node[u];
        edge[cnt_edge].v=v;
        node[u]=cnt_edge++;
    }
    void tarjan(int u)
    {
        int i, j, v;
        dfn[u]=low[u]=++index;
        stack[++top]=u;
        instack[u]=1;
        for(i=node[u]; i!=-1; i=edge[i].next)
        {
            v=edge[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u], low[v]);
            }
            else if(instack[v])
                low[u]=min(low[u], dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            cnt_tar++;
            do
            {
                j=stack[top--];
                instack[j]=0;
                belong[j]=cnt_tar;
            }while(j!=u);
        }
    
    }
    void solve()
    {
        int i;
        top=0, index=0, cnt_tar=0;
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        for(i=1; i<=n; i++)
            if(!dfn[i])
                tarjan(i);
    }
    int main()
    {
        int i, u, v;
        while(scanf("%d%d", &n, &m)!=EOF)
        {
            cnt_edge=0;
            memset(node, -1, sizeof(node));
            for(i=1; i<=m; i++)
            {
                scanf("%d%d", &u, &v);
                ee[i][0]=u, ee[i][1]=v;
                add_Edge(u, v);
            }
            solve();
            for(i=1; i<=m; i++)
            {
                int xx=belong[ee[i][0]], yy=belong[ee[i][1]];
                if(xx!=yy)
                    out[xx]++;
            }
            int mark=0, tot=0;
            for(i=1; i<=cnt_tar; i++)
                if(out[i]==0)
                {
                    tot++;
                    mark=i;
                }
            if(tot>1)
                printf("0
    ");
            else if(tot==1)
            {
                tot=0;
                for(i=1; i<=n; i++)
                    if(belong[i]==mark)
                        tot++;
                printf("%d
    ", tot);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java内部类
    接口与继承
    数据结构
    数据I/O流
    课程总结
    第六次实训作业异常处理
    常用类的课后作业
    窗口实训1
    实训作业4
    实训作业3
  • 原文地址:https://www.cnblogs.com/Hilda/p/3226715.html
Copyright © 2020-2023  润新知