ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

POJ 2186 Popular Cows (korasaju 算法)

2020-07-29 11:32:52  阅读:336  来源: 互联网

标签:cnt int VM scc POJ 2186 Cows id 红人


Description

每头牛都想成为牛群中的红人。给定n头牛和m个有序对(a,b),(a,b)表示牛a认为牛b是红人。该关系有传递性,所以如果牛a认为牛b是红人,牛b认为牛c是红人,那么牛a认为牛c也是红人。求被其他所有牛认为是红人的牛的总数

Input

第一行两个整数n和m表示牛数和关系数,之后m行每行两个整数a和b表示牛a认为牛b是红人

Output

输出被其他所有牛认为是红人的牛的个数

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

Solution

题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性 比如说A觉得B是popular and B thinks C is popular, then A thinks C is popalur also;
现在问有多少头牛是会被其他牛都仰慕。

思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕 算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0(不满足要求) 刚学korasaju 算法,所以用它做

Code

//Kosaraju 算法
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int VM=10010;
const int EM=50010;

struct Edge{
    int to,nxt;
}edge1[EM],edge2[EM];

int head1[VM],head2[VM],n,cnt;
int scc_id[VM],vis[VM],order[VM],k,scc;
int indeg[VM],outdeg[VM];

void addedge(int cu,int cv){
    edge1[cnt].to=cv;
    edge1[cnt].nxt=head1[cu];
    head1[cu]=cnt;

    edge2[cnt].to=cu;
    edge2[cnt].nxt=head2[cv];
    head2[cv]=cnt++;
}

void DFS(int u){
    for(int i=head1[u];i!=-1;i=edge1[i].nxt){
        int v=edge1[i].to;
        if(!vis[v]){
            vis[v]=1;
            DFS(v);
        }
    }
    order[++k]=u;
}

void reDFS(int u){
    for(int i=head2[u];i!=-1;i=edge2[i].nxt){
        int v=edge2[i].to;
        if(!scc_id[v]){
            scc_id[v]=scc;
            reDFS(v);
        }
    }
}

void Korasaju(){
    int i,u;
    k=scc=0;
    memset(vis,0,sizeof(vis));
    memset(scc_id,0,sizeof(scc));
    memset(order,0,sizeof(order));
    for(u=1;u<=n;u++)
        if(!vis[u]){
            vis[u]=1;
            DFS(u);
        }
    for(i=n;i>0;i--){
        u=order[i];
        if(!scc_id[u]){
            scc_id[u]=++scc;
            reDFS(u);
        }
    }
}

void Count_deg(){
    memset(indeg,0,sizeof(indeg));
    memset(outdeg,0,sizeof(outdeg));
    for(int u=1;u<=n;u++)
        for(int i=head1[u];i!=-1;i=edge1[i].nxt){
            int v=edge1[i].to;
            if(scc_id[u]!=scc_id[v]){
                indeg[scc_id[v]]++;
                outdeg[scc_id[u]]++;
            }
        }
}

int main(){

    //freopen("input.txt","r",stdin);

    int m;
    while(~scanf("%d%d",&n,&m)){
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        cnt=0;
        int u,v;
        while(m--){
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        Korasaju();
        Count_deg();
        int count=0,loc;
        for(int i=1;i<=scc;i++)
            if(outdeg[i]==0){
                count++;
                loc=i;
            }
        if(count>1)
            printf("0\n");
        else{
            count=0;
            for(u=1;u<=n;u++)
                if(scc_id[u]==loc)
                    count++;
            printf("%d\n",count);
        }
    }
    return 0;
}

标签:cnt,int,VM,scc,POJ,2186,Cows,id,红人
来源: https://www.cnblogs.com/RioTian/p/13396097.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有