zoukankan      html  css  js  c++  java
  • BZOJ1051 [HAOI2006]受欢迎的牛(Tarjan缩点)

    题意:

    在一个有向图中,求一个点集的大小,这个点集里所有的点都由图中的其他点到达

    思路:

    这个点集一定是一个强连通分量

    先对有向图进行缩点变成DAG,DAG中出度为0的点如果只有一个,那答案就是这个,否则没有答案

    /**************************************************************
        Problem: 1051
        User: wrjlinkkkkkk
        Language: C++
        Result: Accepted
        Time:116 ms
        Memory:2724 kb
    ****************************************************************/
     
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    //#include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x)) 
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 100003;
    const int maxn = 2e5+100;
    const int maxm = 2e5+100;
    const ll inf = 0x3f3f3f3f3f3f3f3f;
    const db pi = acos(-1.0);
    int color[10010],dfn[20020],low[20020],stack[20020],vis[10010],cnt[10010];
    int top,n,m,sum,ans;
    int deep = 0;
    vector<int>g[10010];
    vector<int>rg[10010];
    void tarjan(int u){
        dfn[u]=++deep;
        low[u]=deep;
        vis[u]=1;
        stack[++top]=u;
        int sz=g[u].size();
        for(int i=0;i<sz;i++){
            int v=g[u][i];
            if(!dfn[v]){
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else{
                if(vis[v]){
                    low[u]=min(low[u],low[v]);
                }
            }
        }
        if(dfn[u]==low[u]){
            color[u]=++sum;
            vis[u]=0;
            while(stack[top]!=u){
                color[stack[top]]=sum;
                vis[stack[top--]]=0;
            }
            top--;
        }
        return;
    }
    int res = 0;
    int num[10010];
    void rb(){
        for(int i = 1; i <= n; i++){
            num[color[i]]++;
            int sz = g[i].size();
            for(int j = 0; j < sz; j++){
                int u = g[i][j];
                if(color[i]!=color[u]){
                    rg[color[i]].pb(color[u]);
                }
            }
        }
        int flg = 0;
        for(int i = 1; i <= sum; i++){
            //printf("%d %d
    ", i, rg[i].size());
            if(rg[i].size()==0){
                if(flg==0)flg = i;
                else flg = -1;
            }
        }
     
        if(flg==-1)flg = 0;
        else flg = num[flg];
        printf("%d", flg);
    }
    int main() {
        sum = 0;
        mem(num, 0);
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= m; i++){
            int from, to;
            scanf("%d %d", &from, &to);
            g[from].pb(to);
        }
        for(int i = 1; i <= n; i++){
            if(!dfn[i])tarjan(i);
        }
        //for(int i = 1; i <= n; i++)printf("%d %d
    ",i, color[i] );
        //printf("%d
    ", sum);
        rb();
        return 0;
    }
  • 相关阅读:
    在页面中控制媒体流的起播点和播放长度
    缓冲区数据转换为字符串输出
    编程中注意的一个问题
    一个整合SQL语句的类
    注意服务器系统日期对防病毒软件的影响
    网络病毒源的排查(2005年3月22日维护记录)
    升级到 Microsoft .NET >Visual Basic 6.0 控件和 .NET 控件的区别
    修改您的站点设计以改善下载体验
    下一版本Windows&reg; CE 开发工具Smart Device Extensions for Microsoft Visual Studio&reg; .NET
    WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/9738957.html
Copyright © 2011-2022 走看看