码迷,mamicode.com
首页 > 其他好文 > 详细

Poj 2186 Popular Cows(Tarjan 强连通缩点)

时间:2018-02-17 22:51:32      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:span   comm   ons   pac   scanf   gre   stream   memset   for   

传送门:Poj 2186

题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛

题解:强连通缩点基础题(虽然我Tarjan和缩点都是对的,但是最终讨论判断的时候写垮了(写了3天。。。。还不是你懒!!!!过年划水这么多天缩点后找出度为零的点个数。然后讨论是否有这样子的点,如果没有则全都是(整个都是强连通图),如果只有一个,那么那个强连通分量所含的牛的个数就是所求解,如果有多个那么都是不是。

#include<iostream>
#include<cstdio>
using namespace std;
const int N =1e4+5;
int head[N];
int nx[N*N];
int to[N*N];
int tot=1;
int vis[N];
int comNum;
int comMap[N];
int Stack[N];
int Stacksize;
int n,m;
int dfn[N],low[N];
int indegree[N],outdegree[N];
int Map[N];
void make_list(int u,int v){
    to[tot]=v;
    nx[tot]=head[u];
    head[u]=tot++;
}
void dfs(int u,int step){
    dfn[u]=low[u]=step;
    vis[u]=1;
    Stack[++Stacksize]=u;
    for(int i=head[u];i;i=nx[i]){
        int v=to[i];
        if(vis[v]==0)dfs(v,step+1);
        if(vis[v]==1)low[u]=min(low[u],low[v]);
    }
    if(dfn[u]==low[u]){
        comNum++;
        int sum=0;
        int k;
        do{
            sum++;
            k=Stack[Stacksize--];
            comMap[k]=comNum;
            vis[k]=2;
        }while(k!=u);
        Map[comNum]=sum;
    }
}
void tarjan(){
    for(int i=1;i<=n;i++){
        if(!vis[i])dfs(i,1);
    }
}
int main(){
    while(~scanf("%d %d",&n,&m)){
        memset(head,0,sizeof(head));
        memset(indegree,0,sizeof(indegree));
        memset(outdegree,0,sizeof(outdegree));
        comNum=Stacksize=0;
        memset(Map,0,sizeof(Map));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<m;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            make_list(a,b);
        }
        tarjan();
        for(int u=1;u<=n;u++){
            for(int i=head[u];i;i=nx[i]){
                int v=to[i];
                if(comMap[u]!=comMap[v]){
                    indegree[comMap[v]]++;
                    outdegree[comMap[u]]++;
                }
            }
        }
        int ans=0;
        int po=0;
        for(int i=1;i<=comNum;i++){
            if(outdegree[i]==0){
                ans+=Map[i];
                po++;
            }
        }
        if(po>1)ans=0;
        printf("%d\n",ans);
    }
    return 0;
}

 

Poj 2186 Popular Cows(Tarjan 强连通缩点)

标签:span   comm   ons   pac   scanf   gre   stream   memset   for   

原文地址:https://www.cnblogs.com/Mrleon/p/8452280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!