zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Nginx 部署多个 web 项目(虚拟主机)
    Nginx 配置文件
    Linux 安装 nginx
    Linux 安装 tomcat
    Linux 安装 Mysql 5.7.23
    Linux 安装 jdk8
    Linux 安装 lrzsz,使用 rz、sz 上传下载文件
    springMVC 拦截器
    spring 事务
    基于Aspectj 注解实现 spring AOP
  • 原文地址:https://www.cnblogs.com/Hilda/p/3226715.html
Copyright © 2011-2022 走看看