zoukankan      html  css  js  c++  java
  • B1051 受欢迎的牛 tarjan缩点

    就是一道tarjan缩点的板子,之前在洛谷做过。但是我发现一个事,就是函数里面有一句话:

    void tarjan(int x)
    {
        dfn[x] = low[x] = ++tot;
        str[++top] = x;
        vis[x] = 1;
        for(int k = lst[x];k;k = a[k].nxt)
        {
            int y = a[k].r;
            if(!dfn[y])
            {
                tarjan(y);
                low[x] = min(low[x],low[y]);
            }
            else if(vis[y])
            {
                low[x] = min(low[x],dfn[y]);
            }
        }
        if(low[x] == dfn[x])
        {
            ans++;
            int v;
            do
            {
                num[ans]++;
                vis[str[top]] = 0;
                v = str[top--];
                col[v] = ans;
            }
            while(x != v);
        }
    }

    其中有一段:

    if(!dfn[y])
            {
                tarjan(y);
                low[x] = min(low[x],low[y]);
            }
            else if(vis[y])
            {
                low[x] = min(low[x],dfn[y]);
            }

    但是变成:

    if(!dfn[y])
            {
                tarjan(y);
                low[x] = min(low[x],low[y]);
            }
            else if(vis[y])
            {
                low[x] = min(low[x],low[y]);
            }

    也是能AC的,然后我又试了一开始的那个板子题,直接改好像也可以。。。为什么,或者这么写到底对不对,有人知道吗?欢迎大佬指点。

    题干:

    Description
      每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
    种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
    牛被所有的牛认为是受欢迎的。
    Input
      第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
    能出现多个A,B)
    Output
    
      一个数,即有多少头牛被所有的牛认为是受欢迎的。
    Sample Input
    3 3
    
    1 2
    
    2 1
    
    2 3
    Sample Output
    1
    HINT
    
    100%的数据N<=10000,M<=50000

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int lst[50010],dfn[50010],low[50010],n,m,tot = 0,str[50010],top = 0,vis[50010];
    int num[50010],chu[50010],col[50010],len = 0,ans;
    struct node
    {
        int l,r,nxt;
    }a[50010];
    void add(int x,int y)
    {
        a[++len].l = x;
        a[len].r = y;
        a[len].nxt = lst[x];
        lst[x] = len;
    }
    void tarjan(int x)
    {
        dfn[x] = low[x] = ++tot;
        str[++top] = x;
        vis[x] = 1;
        for(int k = lst[x];k;k = a[k].nxt)
        {
            int y = a[k].r;
            if(!dfn[y])
            {
                tarjan(y);
                low[x] = min(low[x],low[y]);
            }
            else if(vis[y])
            {
                low[x] = min(low[x],dfn[y]);
            }
        }
        if(low[x] == dfn[x])
        {
            ans++;
            int v;
            do
            {
                num[ans]++;
                vis[str[top]] = 0;
                v = str[top--];
                col[v] = ans;
            }
            while(x != v);
        }
    }
    int main()
    {
        read(n);read(m);
        int x,y;
        duke(i,1,m)
        {
            read(x);read(y);
            add(x,y);
        }
        duke(i,1,n)
        {
            if(!dfn[i])
            tarjan(i);
        }
        duke(i,1,n)
        {
            for(int k = lst[i];k;k = a[k].nxt)
            {
                if(col[a[k].l] != col[a[k].r])
                {
                    chu[col[a[k].l]]++;
                }
            }
        }
        int tot = 0,f = 0;
        duke(i,1,ans)
        {
            if(chu[i] == 0)
            {
                tot ++;
                f = i;
            }
            if(tot >= 2)
            {
                puts("0");
                return 0;
            }
        }
        printf("%d
    ",num[f]);
        return 0;
    }
    代码
  • 相关阅读:
    Vue 路由组件传参的 8 种方式
    JS中通过url动态获取图片大小的方法小结(两种方法)
    基于 Vue.js 实现的精致移动端组件库
    .net core 通过代码创建数据库表
    .net core 框架调用顺序
    POCO的理解
    winform datagridview 同步滚动
    UseIIS
    winform 多个datagridview 之间同步滚动
    winform BackgroundWorker 的用法
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9520745.html
Copyright © 2011-2022 走看看