• 好久没写题解了= =这次是bzoj 1051


    唉= =这道题我都想到了tarjan缩点,但是没有想到最后一步啊= =我们很容易想到反向建边然后缩点,这时候我们看由多少个联通块的入度为0,如果为1个,那就输出这个块的大小,否则输出0;

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 10010;
    const int maxe = 50010;
    
    struct edge {
        int t;
        edge* next;
    }e[maxe * 2], *head[maxn]; int ne = 0;
    
    int n, m;
    
    void addedge(int f, int t) {
        e[ne].t = t, e[ne].next = head[f]; head[f] = e + ne ++;
    }
    
    void read() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; ++ i) {
            int u, v;
            scanf("%d%d", &u, &v);
            addedge(v, u);
        }
    }
    
    int dfs[maxn], back[maxn];
    int s[maxn], top = 0, Index = 0;
    bool vis[maxn]; int num = 0;
    int size[maxn];
    int belong[maxn];
    
    void tarjan(int now) {
        dfs[now] = back[now] = ++ Index; vis[now] = true;
        s[++ top] = now;
        for(edge* p = head[now]; p; p = p-> next) {
            if(!dfs[p-> t]) tarjan(p-> t), back[now] = min(back[now], back[p-> t]);
            else if(vis[p-> t] && back[now] > dfs[p-> t]) { 
                back[now] = dfs[p-> t];
            }
        }
        if(dfs[now] == back[now]) {
            ++ num;
            while(1) {
                belong[s[top]] = num; 
                size[num] ++;
                vis[s[top]] = false;
                if(s[top] == now) break;
                top --;
            }
            top --;
        }
    }
    
    int f[maxn]; int in[maxn];
    bool have[maxn];
    
    void sov() {
        memset(vis, false, sizeof(false));
        memset(size, 0, sizeof(size));
        memset(have, 0, sizeof(have));
        for(int i = 1; i <= n; ++ i) {
            if(!dfs[i]) tarjan(i);
        }
        memset(in, 0, sizeof(in));
        int tol = 0;
        for(int i = 1; i <= n; ++ i) {
            for(edge* p = head[i]; p; p = p-> next) {
                if(belong[p-> t] != belong[i]) {
                    in[belong[p-> t]] ++;
                }
            }
        }
        int pos = 0;
        for(int i = 1; i <= num; ++ i) {
            if(in[i] == 0) tol ++, pos = i;
        }
        if(tol == 1) printf("%d
    ", size[pos]);
        else printf("0
    ");
    }
    
    int main() {
        //freopen("test.in", "r", stdin);
        read(); sov();
        return 0;
    }
    
  • 相关阅读:
    【Delphi】MD5算法(二):应用
    迅雷不能下载FlashPlayer,下载后自动删除,狂汗!!!
    工作笔记1
    GridControl 获取筛选后的数据{笔记}
    Invoke与BeginInvoke[转]
    这几项能力不知道要几年
    你永远不要去做的事1【译】
    window环境变量——心得【转】
    刚做好的网站客服系统,欢迎大家测试
    .Net 2.0里有一个有用的新功能:迭代器
  • 原文地址:https://www.cnblogs.com/ianaesthetic/p/3949974.html
Copyright © 2020-2023  润新知