锦鲤抄 题解

· · 题解

我们发现,只要按照拓扑序倒序删点的话,所有的的有入度的点都是可以删掉的。

此时,与有向无环图情况不同的地方即是多了一些强连通分量,于是考虑缩点转化为有向无环图,接下来只需考虑这些强连通分量内部如何处理即可。

若这个强连通分量有入度,画图可知只要按照一定顺序,整个强连通分量都是可以删去的。

若这个强连通分量没有入度,显然的是至少有一个点删不掉,于是我们贪心的不删点权最小的点即可。

同时,若这个强连通分量内部有自环,整个强连通分量也是可以全部删去的,和这个强连通分量有入度的原理相同。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7fffffff
const ll maxn=2e6+10;
ll flag[maxn],scc[maxn],per[maxn];
ll n,m,k,U[maxn],V[maxn];
ll low[maxn],vis[maxn],dfn[maxn],tot,cnt;
ll f[maxn],minn[maxn],val[maxn];
vector<ll> G[maxn],si[maxn];
stack<ll> q;
ll p[maxn];
inline bool cmp(ll x,ll y) {return x>y;}
inline void solve(ll u) {
    q.pop();
    if (val[u]<minn[tot]) {f[u]=1;minn[tot]=val[u];}
    per[u]=tot;vis[u]=0;si[tot].push_back(u);
}
inline void tarjan(ll u) {
    vis[u]=dfn[u]=low[u]=++cnt;
    q.push(u);
    for (ll i=0;i<G[u].size();++i) {
        ll v=G[u][i];
        if (!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if (vis[v]) low[u]=min(low[u],dfn[v]);
    }
    if (dfn[u]==low[u]) {
        ++tot;
        minn[tot]=inf;
        while (q.top()!=u) solve(q.top());
        solve(u);
    }
}
inline ll in() {
    char a=getchar();
    ll t=0,f=1;
    while(a<'0'||a>'9') {if (a=='-') f=-1;a=getchar();}
    while(a>='0'&&a<='9') {t=(t<<1)+(t<<3)+a-'0';a=getchar();}
    return t*f;
}
signed main() {
    n=in(),m=in(),k=in();
    for (ll i=1;i<=n;++i) val[i]=in();
    for (ll i=1;i<=m;++i) {
        U[i]=in(),V[i]=in();
        G[U[i]].push_back(V[i]);
    }
    for (ll i=1;i<=n;++i) if (!dfn[i]) tarjan(i);
    for (ll i=1;i<=m;++i) {
        if (U[i]==V[i]||per[U[i]]!=per[V[i]]) flag[per[V[i]]]=1;
    }
    ll T=0;
    for (ll i=1;i<=tot;++i) {
//      printf("%lld\n",flag[i]);
        for (ll j=0;j<si[i].size();++j) {
            ll u=si[i][j];
            if (f[u]&&minn[i]==val[u]&&!flag[i]) continue;
            p[++T]=val[u];
        }
    } 
//  printf("%lld\n",T);
    sort(p+1,p+1+T,cmp);
    ll ans=0;
    for (ll i=1;i<=k;++i) ans+=p[i];
    printf("%lld",ans);
    return 0;
}