8-1900E - Transitive Graph

发布时间 2023-11-29 20:26:27作者: xxj112

题意:

思路:tarjan缩点后,对新图DAG进行拓扑dp。
代码:

点击查看代码
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=1e6+7;
const int inf=1e9+7;
typedef pair<int,int> pll;
int n,m;
int dfn[N], low[N];
int vis[N];
vector<int> ve[N];
int deep=0;
stack<int> s;
int  color[N];
int sum=0;
void tarjan(int u) {
    dfn[u]=++deep;
    low[u]=deep;
    vis[u]=1;
    s.push(u);
    for(int i=0;i<ve[u].size();i++)
    {
        int v=ve[u][i];
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else
        {
            if(vis[v])
            {
                low[u]=min(low[u],low[v]);
            }
        }
    }
    if(dfn[u]==low[u])
    {
        color[u]=++sum;
        // cout<<u<<" "<<sum<<"s\n";
        vis[u]=0;
        while(s.size()&&s.top()!=u)
        {
            color[s.top()]=sum;
            vis[s.top()]=0;
            s.pop();
        }
        s.pop();
    }

}
pll w[N];
int a[N];
vector<int> v2[N];
vector<int> v3[N];
int rd[N];
void init()
{
    for(int i=1;i<=n;i++)
    {
        w[i]={0,0};
        v2[i].clear();
        ve[i].clear();
        v3[i].clear();
        vis[i]=0;
        dfn[i]=low[i]=0;
    }
    deep=0;
    sum=0;
    while(s.size())
    {
        s.pop();
    }
}
void solve()
{
    cin>>n>>m;
    init();
    int x,y,z;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        ve[x].push_back(y);
    }
    for(int i=1;i<=n;i++)
    {
        if(!dfn[i]) tarjan(i);
        //cout<<dfn[i]<<" ";
    }   
    for(int i=1;i<=n;i++)
    {
        w[color[i]].first++;
        w[color[i]].second+=a[i];
      //  cout<<color[i]<<" ";
        for(auto v:ve[i])
        {
            if(color[v]!=color[i])
            {
                v2[color[i]].push_back(color[v]);
                v3[color[v]].push_back(color[i]);
                rd[color[v]]++;
            }
        }
    }
    int a1=0,a2=0;
    queue<int> q; 
    for(int i=1;i<=sum;i++)
    {
        if(rd[i]==0)
        {   
            q.push(i);

        }
      //  cout<<w[i].first<<" "<<w[i].second<<" w\n";
    }
    while(q.size())
    {
        int w1=q.front();
        q.pop();
        // cout<<w1<<endl;
        for(auto v:v2[w1])
        {
            rd[v]--;

            if(rd[v]==0)
            {
                q.push(v);
                int b1=0,b2=0;
             
                for(int i=0;i<v3[v].size();i++)
                {
                    int ss=v3[v][i];
                    if(w[ss].first>b1)
                    {
                        b1=w[ss].first;
                        b2=w[ss].second;
                    }
                    else if(w[ss].first==b1)
                    {
                        b2=min(w[ss].second,b2);
                    }
                }

                w[v].first+=b1;
                w[v].second+=b2;
            }
            
        }
    }
    for(int i=1;i<=sum;i++)
    {
        if(w[i].first>a1)
        {
            a1=w[i].first;
            a2=w[i].second;
        }
        else if(w[i].first==a1)
        {
            a2=min(w[i].second,a2);
        }
    }
    
        cout<<a1<<" "<<a2<<"\n";
}
signed  main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

   
    int t=1;
    cin>>t;
    while(t--)
    {
        solve();
    }
    return 0;
}