zoukankan      html  css  js  c++  java
  • P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G

    题目传送门!!

    经典强联通题目。

    对于一个强联通,如果其出度为0,则其中所有的奶牛都为明星。

    注意,如果出现两个以上出度为0的强联通,则无法做到“被全部喜欢”, 应该特判输出“0”。

    #include <bits/stdc++.h>
    using namespace std;
    #define N 100010
    #define isdigit(c) ((c)>='0'&&(c)<='9')
    
    int read(){
        int x = 0, s = 1;
        char c = getchar();
        while(!isdigit(c)){
            if(c == '-')s = -1;
            c = getchar();
        }
        while(isdigit(c)){
            x = (x << 1) + (x << 3) + (c ^ '0');
            c = getchar(); 
        } 
        return x * s;
    } 
    
    int dfn[N], low[N], scc[N];
    int stac[N], top = 0;
    bool vis[N]; 
    
    struct node{
        int u, v, next;
    } t[N];
    int f[N];
    int out[N];
    
    int bian = 0;
    inline void add(int u, int v){
        t[++bian] = (node){u, v, f[u]};
        f[u] = bian;
        return ;
    }
    
    int cac = 0, cnt = 0;
    void tarjan(int now){  /*tarjan 板子*/
        dfn[now] = low[now] = ++cac;
        stac[++top] = now;
        vis[now] = 1;
        for(int i = f[now]; i; i = t[i].next){
            int v = t[i].v;
            if(!dfn[v]){
                tarjan(v);
                low[now] = min(low[now], low[v]);
            }
            else if(vis[v]) low[now] = min(low[now], dfn[v]);
        }
        if(low[now] == dfn[now]){
            int cur;
            cnt++;
            do{
                cur = stac[top--];
                vis[cur] = 0;
                scc[cur] = cnt;
            } while(cur != now);
        }
        return ;
    }
    
    int main(){
        int n = read(), m = read();
        for(int i = 1;i <= m; i++){
            int x = read(), y = read();
            add(x, y);
        }
        for(int i = 1;i <= n; i++)
            if(!dfn[i])  tarjan(i);
        for(int i = 1;i <= bian; i++){
            int u = t[i].u, v = t[i].v;
            if(scc[u] != scc[v])
                out[scc[u]] ++;   /*记录出度*/
        }
        int flag = 0, id = 0;
        for(int i = 1;i <= cnt; i++){
            if(out[i] == 0){
                flag++;
                id = i;
            }
        }
        int ans = 0;
        for(int i = 1;i <= n; i++)
            ans += scc[i] == id;
        if(flag > 1) printf("0");
        else printf("%d
    ", ans);
        return  0;
    }
  • 相关阅读:
    POJ1275 Cashier Employment 【二分 + 差分约束】
    POJ1201 Intervals 【差分约束】
    BZOJ1563/洛谷P1912 诗人小G 【四边形不等式优化dp】
    BZOJ4197 [Noi2015]寿司晚宴 【状压dp】
    thusc2018酱油记
    HDU 4734
    Codeforces 55D
    HDU 3652
    HDU 4352
    HDU 3709
  • 原文地址:https://www.cnblogs.com/wondering-world/p/12991626.html
Copyright © 2011-2022 走看看