题解[Luogu P5008 [yLOI2018] 锦鲤抄]

题目

Link

这首歌很好听。

就是因为喜欢歌才来做这道题的

一道很不错的贪心题,对思维的启发极大。

Sol

Sub1

暴搜即可。

是不是有模拟赛题解那味了

Sub2

这个\(subtask\)十分关键,直接让我们有通向正解的思路。

发现,如果图是一个有向无环图,那我们根据反向拓扑序来选点,只要不是一开始就没入度的点,一定是可以选的。这样就为我们提供了做法:除去本无入度的点以外,其他点随便选。

正是这一个有向无环图 ,让我们往缩点方向思考。

正解

手动画两个图,两个图都带一个环,一个环有入度,一个环没入度:

有入度的:

题解[Luogu P5008 [yLOI2018] 锦鲤抄]

按照\(1->4->3->2\)的顺序可以取遍所有点。

没入度的:

题解[Luogu P5008 [yLOI2018] 锦鲤抄]

无论怎样都有一个点取不到。

那我们的结论就有了:

缩点以后,有入度的环里的点随便选,其他的环舍掉最小的不选。

Talk is cheap,show you the code.

Code

#include<bits/stdc++.h>
#define M (2000010)
#define N (2000010)
using namespace std;
struct xbk{int ed,nx;}e[M];
int n,m,k,top,cnt,tot,ans,color,x[N],y[N],v[N];
int head[N],rd[N],dfn[N],low[N],stk[N],col[N];
bool used[N];
priority_queue<int>q;
vector<int>son[N];
inline int read(){
	int w=0;
	char ch=getchar();
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch>='0'&&ch<='9'){
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w;
}
inline void add(int a,int b){
	e[++cnt].ed=b;
	e[cnt].nx=head[a];
	head[a]=cnt;
}
inline void Tarjan(int st){
	dfn[st]=low[st]=++tot;
	used[st]=1,stk[++top]=st;
	for(int i=head[st];i;i=e[i].nx){
		int ed=e[i].ed;
		if(!dfn[ed]){
			Tarjan(ed);
			low[st]=min(low[st],low[ed]);
		}
		else if(used[ed]) low[st]=min(low[st],dfn[ed]);
	}
	if(dfn[st]==low[st]){
		color++;
		while(stk[top+1]!=st){
			son[color].push_back(stk[top]);
			col[stk[top]]=color;
			used[stk[top--]]=0;
		}
	}
	return;
}
int main(){
	n=read(),m=read(),k=read();
	for(int i=1;i<=n;i++) v[i]=read();
	for(int i=1;i<=m;i++){
		x[i]=read(),y[i]=read();
		add(x[i],y[i]);
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=m;i++)
		if(col[x[i]]!=col[y[i]]) rd[col[y[i]]]++;
	for(int i=1;i<=color;i++){
		if(rd[i])
			for(int j=0;j<(int)son[i].size();j++) q.push(v[son[i][j]]);
		else{
			int mn=v[son[i][0]];
			for(int j=1;j<(int)son[i].size();j++){
				if(v[son[i][j]]>=mn) q.push(v[son[i][j]]);
				else q.push(mn),mn=v[son[i][j]];
			}
		}
	}
	for(int i=1;i<=k;i++){
		ans+=q.top(),q.pop();
		if(q.empty()) break;
	}		
	printf("%d\n",ans);
	return 0;
}

完结撒花❀

上一篇:(数论)同余定理


下一篇:A-color-image-encryption-technique-using-exclusive-OR-with-DNA-complementary-rules-based-on-chaos...