2024 ICPC ShaanXi Provincial Contest C. Seats

2024 ICPC ShaanXi Provincial Contest C. Seats

题目链接:

C.Seats

正经题意:

给出长为 n 数组 ai, 你需要找到长为 n 的数组 bi(1 ≤ i ≤ n, 1 ≤ bi ≤ 2n) 满足 ∀i ̸= j, bi ̸= bj 且 ∀i, bi = i 或 bi = ai。最大化 bi = ai 的个数并输出最大值。

简而言之:

其实就是在基环树森林和森林中找两个东西
1.成环的结点个数
2.森林中所有以 (>n <=n*2)为根的最长路的和

思路:

进行拓扑排序,可以轻易分割基环树森林和森林,不在拓扑序列中的一定成环!可以直接解决我们要的第一个东西。
第二个东西只需要记录下逆向边,从每个结点出发寻找最长路即可

代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 2e6+26;
typedef long long LL;
int e[N],ne[N],h[N],idx;
int d[N];int dist[N];int dd[N];
int q[N];int p[N];int p2[N];int p3[N];
int p4[N];
int e2[N],ne2[N],h2[N],idx2;

void add1(int a,int b){
	e[idx] = b,ne[idx] = h[a],h[a] = idx++;	
}
void add2(int a,int b){
	e2[idx2] = b,ne2[idx2] = h2[a],h2[a] = idx2++;
}
int n,m;	int tt=-1,hh=0;

void topsort(){
	for(int i = 1;i<=n;i++){
		if(d[i]==0) q[++tt] = i;
	}
	while(hh<=tt){
		int head = q[hh++];
		if(h[head]==-1) continue;
		int j = e[h[head]];
		d[j]--;
		if(d[j]==0) q[++tt] = j;
	}
}

int main(){
	scanf("%d",&n);
	memset(h,-1,sizeof h);
	memset(h2,-1,sizeof h2);
	for(int i = 1;i <= n;i++){
		int x;
		scanf("%d",&x);
		if(i==x) p2[i] = 1;//标记是否是自环 
		add1(i,x);//正边 
		add2(x,i);//逆边 
		d[x]++;
	}

	topsort();//拓扑排序找出不是环的结点 
	int cott=0;
	for(int i = 0;i<=n*2-1;i++){
		if(q[i]!=0) p3[q[i]]++;
	}
	for(int i = 1;i<=n;i++){
		if(p3[i]) cott++;
	}
	int ccoo=n-cott;
	if(tt==-1) ccoo = n;
	
	LL sum = ccoo;
	for(int i = n+1;i<=2*n;i++){
		queue<int> qq;
		qq.push(i);
		int maxa = 0;
		while(qq.size()){
			int x = qq.front();
			qq.pop();
			if(h2[x]==-1) continue;
			for(int j = h2[x];j!=-1;j=ne2[j]){
				int k = e2[j];
				if(x == k) break;
				if(p3[k]==0) break;
				dist[k] = max(dist[k],dist[x]+1);
				maxa = max(dist[k],maxa);
				qq.push(k);
			}			
		}
		sum += maxa;
	}
	
	printf("%d",sum);
	return 0;
}
  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UIUC ICPC Spring Coding Contest 2019是UIUC(伊利诺伊大学厄巴纳-香槟分校)举办的一个编程比赛。UIUC ICPC Spring Coding Contest 2019是ACM国际大学生程序设计竞赛(ACM International Collegiate Programming Contest)的一部分。ACM国际大学生程序设计竞赛是世界上最具影响力的大学生计算机竞赛之一,每年吸引了来自全球各地的大学生参与。这个比赛旨在培养学生的算法和编程技能,提供一个展示和交流的平台。参赛者需要在规定时间内解决一系列编程问题。 参加UIUC ICPC Spring Coding Contest 2019对于那些对算法和编程有兴趣的学生来说,是一个很好的学习和锻炼机会。比赛中的问题通常涉及各种算法和数据结构,要求参赛者能够用编程语言实现有效和高效的解决方案。参赛者可以通过解决问题来提高他们的算法和编程技能,并与其他参赛者交流和学习。 在准备UIUC ICPC Spring Coding Contest 2019之前,建议参赛者先掌握一些基本的编程知识和技能,如数据结构、算法、编程语言等。参赛者可以参考一些相关的教程和学习资料,如GeeksforGeeks和HackerEarth等网站提供的编程教程。此外,还可以参考一些竞赛经验分享的文章和博客,了解其他人是如何准备和参加编程比赛的。 总之,参加UIUC ICPC Spring Coding Contest 2019是一个很好的机会,可以提高算法和编程技能,与其他参赛者交流和学习。准备比赛前,建议参赛者掌握基本的编程知识和技能,并参考一些相关的教程和学习资料。祝你在比赛中取得好成绩!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Awesome Competitive Programming Awesome](https://blog.csdn.net/qq_27009517/article/details/86593200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值