yLOI2018锦鲤抄
Posted shxnb666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yLOI2018锦鲤抄相关的知识,希望对你有一定的参考价值。
题面
https://www.luogu.org/problem/P5008
题解
为了带入氛围还把$QQ$音乐里的《锦鲤抄》点开听了听。
让我们想想删除的顺序是什么样子的:最优的顺序一定是从拓扑序最大的点倒着删,删到拓扑序最小的点。
其中有入度的强连通分量可以全都删完(最后通过“入度”退回拓扑序小的强连通分量)如果最后一个了,就必须留一个点。
贪心即可。
#include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 500500 #define M 2000500 #define mod 1000000007 #define ri register int using namespace std; inline int read() int ret=0; char ch=getchar(); while (ch<‘0‘ || ch>‘9‘) ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) ret*=10,ret+=(ch-‘0‘),ch=getchar(); return ret; stack<int> s; vector<int> to[N]; int dfn[N],low[N],a[N],bel[N],id[N]; int n,m,k,u[M],v[M],sc=0,vc=0,ins[N],siz[N]; void tarjan(int x) dfn[x]=low[x]=++sc; s.push(x); ins[x]=1; for (ri i=0;i<to[x].size();i++) int y=to[x][i]; if (!dfn[y]) tarjan(y); low[x]=min(low[x],low[y]); else if (ins[y]) low[x]=min(low[x],dfn[y]); if (low[x]==dfn[x]) ++vc; while (1) int t=s.top(); s.pop(); ins[t]=0; bel[t]=vc; siz[vc]++; if (t==x) break; bool cmp(int x,int y) return a[x]>a[y]; int main() n=read(); m=read(); k=read(); for (ri i=1;i<=n;i++) a[i]=read(); for (ri i=1;i<=m;i++) u[i]=read(); v[i]=read(); to[u[i]].push_back(v[i]); for (ri i=1;i<=n;i++) if (!dfn[i]) tarjan(i); for (ri i=1;i<=m;i++) if (bel[u[i]]!=bel[v[i]]) siz[bel[v[i]]]++; for (ri i=1;i<=n;i++) id[i]=i; sort(id+1,id+n+1,cmp); int ans=0,cnt=0; for (ri i=1;i<=n;i++) int cur=id[i]; if (siz[bel[cur]]>1) siz[bel[cur]]--; ans+=a[cur]; if (++cnt==k) printf("%d\n",ans); return 0; printf("%d\n",ans); return 0;
以上是关于yLOI2018锦鲤抄的主要内容,如果未能解决你的问题,请参考以下文章