zoukankan      html  css  js  c++  java
  • poj2186【利用强连通分量】

    题意:
    有n头奶牛,然后有个规则是A->B,B->C,那么A->C;
    A觉得B受欢迎,B觉得C受欢迎,那么A觉得C受欢迎;
    求:被其他所有牛都欢迎的牛的数量;
    思路:
    原来的思路:
    我们只要在缩点之后的图中,找出出度为0的点,然后输出它里面的点就可以了。【虽然AC了】
    然后我觉得这样不是会有缺陷么?他可能入度也为0呢?也就是缩点后那个出度为0点是独立的。所以还是要判断入度吧。
    后来其实没必要入度,我们继续查看其他出度为0的点,如果存在的话那肯定是有独立的部分,然后如果没有的话,嘿嘿,那么肯定就是他了。
    总结:
    利用tarjan算法可以办到缩点。
    然后主要的思路就是:在一张图里面,经过缩点后,出度为0的点只有一个的话,那么他肯定被其他点在一定程度上给盯上了。
    —————————————歌:飞得更高–汪峰

    //#include <bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<math.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    const double eps=1e-6;
    const double pi=acos(-1.0);
    const int mod=998244353;
    const int INF=0x3f3f3f3f;
    
    const int N=1e4+8;
    
    struct asd{
        int to;
        int next;
    };
    asd q[N*5];
    int head[N*5],tol;
    
    int n;
    int dfn[N];
    int low[N];
    int st[N],vis[N],in[N];
    int p,tp,sum;
    int kr[N];
    int xx[N];
    
    void INIT()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void add(int a,int b)
    {
        q[tol].to=b;
        q[tol].next=head[a];
        head[a]=tol++;
    }
    
    void tarjan(int u)
    {
        dfn[u]=low[u]=++p;
        st[++tp]=u;
        vis[u]=1;
        for(int i=head[u];i!=-1;i=q[i].next)
        {
            int x=q[i].to;
            if(!dfn[x]){
                tarjan(x);
                low[u]=min(low[u],low[x]);
            }
            else if(vis[x]){
                low[u]=min(low[u],dfn[x]);
            }
        }
        if(dfn[u]==low[u]){
            int temp;
            sum++;
            while(1){
                temp=st[tp];
                in[temp]=sum;
                vis[temp]=0;
                tp--;
                if(temp==u){
                    break;
                }
            }
        }
    }
    
    
    void solve()
    {
        memset(kr,0,sizeof(kr));
        memset(xx,0,sizeof(xx));
        for(int i=1;i<=n;i++){
            for(int v=head[i];v!=-1;v=q[v].next){
                int t=q[v].to;
                if(in[t]!=in[i]){
                    kr[in[i]]++;
                }
            }
        }
        int ans=0,num=0,k;
        for(int i=1;i<=sum;i++){
            if(!kr[i]){
                num+=1;
                k=i;
            }
        }
        if(num==1){
            for(int i=1;i<=n;i++)
            {
                if(in[i]==k){
                    ans++;
                }
            }
            printf("%d
    ",ans);
        }
        else{
            puts("0");
        }
    }
    
    int main()
    {
        int a,b,m;
        scanf("%d%d",&n,&m);
        INIT();
        while(m--){
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        tp=p=sum=0;
        memset(vis,0,sizeof(vis));
        memset(low,0,sizeof(low));
        for(int i=1;i<=n;i++)
        {
            if(!dfn[i]){
                tarjan(i);
            }
        }
        solve();
        return 0;
    }
    
  • 相关阅读:
    hdu1865 1sting (递归+大数加法)
    hau1021 Fibonacci Again(递归)
    hdu2553 N皇后问题(dfs+回溯)
    BZOJ2342 [Shoi2011]双倍回文 【manacher】
    Manacher算法学习 【马拉车】
    BZOJ2743 [HEOI2012]采花 【离线 + 树状数组】
    BZOJ1296 [SCOI2009]粉刷匠 【dp】
    BZOJ1086 [SCOI2005]王室联邦 【dfs + 贪心】
    BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】
    BZOJ2157 旅游 【树剖 或 LCT】
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934428.html
Copyright © 2011-2022 走看看