zoukankan      html  css  js  c++  java
  • Poj 2186 Popular Cows(Tarjan 强连通缩点)

    传送门: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
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    unity 编辑器 对比两次节点信息 查看新增节点和消失节点。
    根据模型的Height进行颜色的渐变 (Shader相关)
    TimeLine一些思考
    (unity小工具)C# 获取选择的Gameobject对象被引用的类名和字段名
    copy节点相对prefab的路径 (unity小工具)
    使用LineRender绘制网格线
    龙书11_chapter_6 二:HillsDemo解析
    龙书11_chapter_6 一:一般绘制流程
    龙书11_chapter_4 三:每一小节关键点
    龙书11_chapter_4 二:习题中的Adapter
  • 原文地址:https://www.cnblogs.com/Mrleon/p/8452280.html
Copyright © 2011-2022 走看看