• luogu P2194 HXY烧情侣


    残忍的题面

    我们来看这一道题,其实冗长的题目告诉我们一个核心——用tarjan

    tarjan是用来干什么呢?是用来求强连通分量(代码中指sc)

    求出来又有什么用呢?每当我们求出一个强连通分量时,就去计算当前强连通分量中各点最小值是多少以及其个数

    然后分别开两个计数器,假设ans1是用来存个数相乘,ans2是用来累加最小值的。

    临门一脚,千万别忘了取% 另外注意如果小伙伴这样和我一样写tarjan的话

    for(int i=head[x];i!=-1;i=e[i].next)

    一定记住,在main函数里要

    memset(head,-1,sizeof(head));

    (看本蒟蒻的代码,大神勿喷)

    #include<bits/stdc++.h>
    using namespace std;
    const int mod = 1e9+7;
    #define ll long long
    #define inf 1e9
    const int N = 310000;
    const int M = 210000;
    int head[M],v[M],dfn[M],low[M],q[M];
    int be[M],sum[M],hh[M],num[M];
    int ss,n,m,now,cnt,tot,sc;
    ll ans1=1,ans2;
    bool f[N];
    struct Edge{
        int to,next;
    }e[N];
    void add(int x,int y)
    {
        e[++ss].to=y;
        e[ss].next=head[x];
        head[x]=ss;
    }
    void dfs(int x)//这里的dfs和下面tarjan分着写的,不管怎样都是tarjan模板
    {
        low[x]=dfn[x]=++cnt;
        q[++tot]=x;
        f[x]=1;
        for(int i=head[x];i!=-1;i=e[i].next)
        {
            if(!dfn[e[i].to])
            {
                dfs(e[i].to);
                low[x]=min(low[x],low[e[i].to]);
            }
            else
            if(f[e[i].to])
            low[x]=min(low[x],dfn[e[i].to]);
        }
        if(low[x]==dfn[x])
        {
            sc++;
            be[x]=sc;
            hh[sc]=inf;
            do
            {
                now=q[tot--];
                f[now]=0;
                be[now]=sc;
                if(v[now]<hh[sc])
                {
                    hh[sc]=v[now];
                    num[sc]=0;
                }
                if(v[now]==hh[sc]) num[sc]++;
            }
            while(now!=x);
        }
    }
    void tarjan()
    {
        for(int i=1;i<=n;i++)
            if(!dfn[i]) dfs(i);
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>v[i];
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            int x,y;
            cin>>x>>y;
            add(x,y);
        }
        tarjan();
        for(int i=1;i<=sc;i++)//最后的处理,ans1别忘初值为1
        {
            ans1*=num[i];
            ans2+=hh[i];
            ans1%=mod;
        }
        cout<<ans2<<" "<<ans1;
        return 0;
    }
  • 相关阅读:
    MyBatis与spring面试题-转载
    122. 买卖股票的最佳时机 II(贪心策略)
    121. 买卖股票的最佳时机
    120. 三角形最小路径和
    236. 二叉树的最近公共祖先(快手面试)
    b,b+树区别
    119. 杨辉三角 II
    118. 杨辉三角
    检查型异常(Checked Exception)与非检查型异常(Unchecked Exception)
    Redis
  • 原文地址:https://www.cnblogs.com/xmex/p/10168581.html
Copyright © 2020-2023  润新知