zoukankan      html  css  js  c++  java
  • 今天的第二道tarjan:受欢迎的牛

    原题来自:USACO 2003 Fall

    题目描述

    每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果 AAA 喜欢 BBB,BBB 喜欢 CCC,那么 AAA 也喜欢 CCC。牛栏里共有 NNN 头奶牛,给定一些奶牛之间的爱慕关系,请你算出有多少头奶牛可以当明星。

    输入格式

    第一行:两个用空格分开的整数:NNN 和 MMM。

    接下来 MMM 行:每行两个用空格分开的整数:AAA 和 BBB,表示 AAA 喜欢 BBB。

    输出格式

    一行单独一个整数,表示明星奶牛的数量。

    输入输出样例

    输入 #1
    3 3
    1 2
    2 1
    2 3
    输出 #1
    1

    说明/提示

    只有 3 号奶牛可以做明星。

    数据范围

    题解

    emmmm

    这是一到极为经典的,似乎是这一类题的模板的题目:缩点
    缩点,也是tarjan的极大的一个作用。
    缩点只对强联通分量有用,因为强联通分量中的点可以互相到达,可以被视为一个点。

    这题,是肯定是有环的。
    那么肯定是很不好去实现遍历的。
    怎么办呢?
    根据常识,环上的点肯定都在同一个强联通分量中。
    强联通分量 -->缩点
    经过缩点的图,一定是一个有向无环图
    那么只需要一个dfs就好了啊awa
    简单题
    awa
    淦,题解写完了,代码还没写。。。

    等等我写完代码awa

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    struct edge
    {
        int next,to;
    }e[1000001];
    int head[1000001],n,m,w[1000001],tot,ccs,dfsc,low[1000001],dfn[1000001],color[10000001],cnt[1000001],de[1000001],all[1000001];bool vis[1000001];
    stack<int> stk;
    inline ll read()
    {
        char c=getchar();ll a=0,b=1;
        for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
        for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;
        return a*b;
    }
    void add(int i,int j)
    {
        e[++tot].next=head[i];
        e[tot].to=j;
        head[i]=tot;
    }
    void tarjan(int x,int fa)
    {
        dfn[x]=low[x]=++dfsc;
        vis[x]=true;stk.push(x);
        for(int i=head[x];i!=0;i=e[i].next)
        {
            int u=e[i].to;
    //        if(u==fa)continue;
            if(dfn[u]==0)
            {
                tarjan(u,x);
                low[x]=min(low[x],low[u]);
            }
            else
            if(vis[u]==true)
            {
                low[x]=min(low[x],dfn[u]);
            }
        }
        if(dfn[x]==low[x])
        {
            int k;
            ccs++;
            do
            {
                k=stk.top();
                stk.pop();
                color[k]=ccs;
                cnt[ccs]++;all[ccs]++;
                vis[k]=false;
            }
            while(x!=k);
        }
    }
    int main()
    {
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            int x=read();int y=read();
            add(x,y);
        }
        for(int i=1;i<=n;i++)
        {
            if(dfn[i]==0)
            {
                tarjan(i,-1);
            }
        }
    //    for(int i=1;i<=n;i++)
    //    {
    //        cout<<color[i]<<endl;
    //    }
        for(int i=1;i<=n;i++)
        {
            int x=i;
            for(int j=head[x];j!=0;j=e[j].next) 
            {
                int u=e[j].to;
                if(color[u]!=color[x])
                {
                    de[color[i]]++;
                }
            }
        }
        int ans=0,sum=0;bool tt=0;
        for(int i=1;i<=ccs;i++)
        {
            if(de[i]==0)
            {
                ans+=cnt[color[i]];
                sum++;
                if(tt){puts("0");return 0;}
                tt=i;
            }
        }
        cout<<all[tt]<<endl;
        return 0;
    }

     n年前的草稿总算是发布了awa

  • 相关阅读:
    HDU 2192 MagicBuilding
    HDU 2148 Score
    HDU 1847 Good Luck in CET4 Everybody!
    往CImageList中加图标列表
    LoadIcon
    OnInitialUpdate 详解
    设备坐标(DP)、客户坐标(Client)、逻辑坐标(LP)
    Web及网络基础学习(一)
    Qt 下QMessageBox下中文乱码问题
    vs2005菜单:选项项目和解决方案
  • 原文地址:https://www.cnblogs.com/HLZZPawa/p/12804826.html
Copyright © 2011-2022 走看看