ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-04-05 08:32:50  阅读:167  来源: 互联网

标签:ch 没入 int 题解 入度 锦鲤 P5008 mn


题目

Link

这首歌很好听。

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

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

Sol

Sub1

暴搜即可。

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

Sub2

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

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

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

正解

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

有入度的:

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

没入度的:

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

那我们的结论就有了:

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

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;
}

完结撒花❀

标签:ch,没入,int,题解,入度,锦鲤,P5008,mn
来源: https://www.cnblogs.com/xxbbkk/p/14617752.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有