首页 > 其他分享 >Dwango Programming Contest 6th D 题解

Dwango Programming Contest 6th D 题解

时间:2024-03-12 14:48:17浏览次数:30  
标签:tmp 题解 printf Programming st vis 6th now lld

正好测试一下专栏的题解系统。

我省选寄了都怪洛谷/fn/fn/fn/fn/fn/fn/fn

题解

显然可以对于所有关系建有向边,显然是基环外向树森林。

由于是字典序最小,因此找到最小的上一个点没有直接连向边的点一定最优。

但是有时取最优会导致最后无法选完,我们考虑无法选完的情况。

第一种是剩下一朵菊花,具体如上图,选择 1 之后如果选择 2 ,则只能将菊花非根节点取完而无法取根,此时应该先取根。

第二种是剩下一个两个节点的环和一个独立的点,具体如上图,如果在选择 1,3 之后选择 2,则最后 4,5 只能选择一个,此时应该选择 5(4 由于 3 指向无法选择)。

全部特判完即可通过。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL to[200005],sum[200005],num[200005];
LL n,i,j,k,m,maxx=0,x,y;
set<LL> st;
bool vis[200005];
int main(){
	scanf("%lld",&n);
	for(i=1;i<=n;i++){
	    scanf("%lld",&to[i]);
	    sum[to[i]]++;
	}
	for(i=1;i<=n;i++){
		maxx=max(maxx,sum[i]);
		num[sum[i]]++;
	}
	if(n==2 && to[1]==2 && to[2]==1){
		printf("-1");
		return 0;
	}
	for(i=2;i<=n;i++)
	  st.insert(i);
	LL now=0,cnt=0,tmp=1;
	while(cnt<n){
		if(now>0){
			if(vis[to[now]]==false){
				num[sum[to[now]]]--;
				num[--sum[to[now]]]++;	
			}
			num[sum[now]]--;
			while(num[maxx]==0) maxx--;
		}
		cnt++;
		if(st.empty()){
			printf("%lld ",tmp);
			return 0;
		}
		if(maxx==(n-cnt)){
			if(sum[tmp]==maxx){
				printf("%lld ",tmp);
				now=tmp;
				vis[tmp]=true;
				tmp=*st.begin();
				st.erase(tmp);
				continue;
			}
			else if(vis[to[tmp]]==false){
				printf("%lld ",to[tmp]);
				now=to[tmp];
				st.erase(to[tmp]);
				vis[to[tmp]]=true;
				continue;
			}
		}
		if(n-cnt==2){
			x=*st.begin(),st.erase(x);
			y=*st.begin(),st.erase(y);
			if(to[tmp]==x && to[x]==tmp){
				if(to[now]==tmp){
					printf("%lld ",x);
					now=x,vis[x]=true;
					st.insert(y);continue;
				}
				else{
					printf("%lld ",tmp);
					now=tmp,vis[tmp]=true;
					tmp=x,st.insert(y);continue;
				}
			}
			if(to[tmp]==y && to[y]==tmp){
				if(to[now]==tmp){
					printf("%lld ",y);
					now=y,vis[y]=true;
					st.insert(x);continue;
				}
				else{
					printf("%lld ",tmp);
					now=tmp,vis[tmp]=true;
					tmp=x,st.insert(y);continue;
				}
			}
			if(to[x]==y && to[y]==x){
				if(to[now]==x){
					printf("%lld ",y);
					now=y,vis[y]=true;
					st.insert(x);continue;
				}
				else{
					printf("%lld ",x);
					now=x,vis[x]=true;
					st.insert(y);continue;
				}
			}
			st.insert(x),st.insert(y);
		}
		if(tmp==to[now]){
			printf("%lld ",*st.begin());
			now=*st.begin();
			vis[*st.begin()]=true;
			st.erase(*st.begin());
		}
		else{
			printf("%lld ",tmp);
			now=tmp;
			vis[tmp]=true;
			tmp=*st.begin();
			st.erase(tmp);
		}
	}
	return 0;
}

标签:tmp,题解,printf,Programming,st,vis,6th,now,lld
From: https://www.cnblogs.com/monster-hunter/p/18068245

相关文章

  • AtCoder Beginner Contest 344 A-G 题解
    AtCoderBeginnerContest344A-SpoilerQuestion删除两个|之间的字符Solution按照题意模拟即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;stringp1,p2;for(inti=0;i<s.size();i++){......
  • LeetCode - 高频SQL50题(基础版)部分题解(上)
    1581.进店却未进行过交易的顾客原题:https://leetcode.cn/problems/customer-who-visited-but-did-not-make-any-transactions/题意:有一些顾客可能光顾了购物中心但没有进行交易。请你编写一个解决方案,来查找这些顾客的ID(customer_id),以及他们只光顾不交易的次数(count_no_trans......
  • node: /lib64/libm.so.6: version `GLIBC_2.27‘ not found问题解决方案
    场景centos7服务器使用nvm安装的node之后,只要使用npm或者node,均会出现以下问题。npm-vnode:/lib64/libm.so.6:version`GLIBC_2.27'notfound(requiredbynode)node:/lib64/libc.so.6:version`GLIBC_2.25'notfound(requiredbynode)node:/lib64/libc.so.6:ver......
  • 开摆题解
    开摆--更新ing没有详解(大概目录开摆--更新ingA题B题C题D题E题A题不配文字讲解了,具体的直接问我本人吧前缀和视频C++代码voidsolve(){intn,m,w,x,i,ans=0;cin>>n;vector<int>qwq(49);//前缀和数组for(i=0;i<n;++i){cin>......
  • Toyota Programming Contest 2024#3(AtCoder Beginner Contest 344)
    C先预处理出三个数组能拼出的数,存放到map中。查询的时候只需要看这个数是否出现在map里即可。时间复杂度\(O(n^3\logv+Q\logv)\),\(n\leq100\),\(\logv\)是map的时间复杂度。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=3e......
  • rosdep update超时问题解决
    此问题的解决也适用ros11、初始化$sudorosdepinit2、下载rosdistro到本地$gitclonehttps://github.com/ros/rosdistro.git3、修改以下文件,将其url指向本地(1)文件1:20-default.list地址路径:/etc/ros/rosdep/sources.list.d/20-default.list原来内容:#os-specificl......
  • 随机逆序对 题解
    题意给定$1\simn$的排列$a_{1...n}$。在上面进行依次如下操作:首先在$[1,n]$​中选取一个子序列(可以为空);然后将这个子序列内的数重新排列。两个操作不同,当且仅当选取的子序列不同或者重新排列的方式不同。对于所有不同的操作,求他们产生的排列的逆序对个数和,答案......
  • 【蓝桥-大试牛刀7-最短路专场】题解
    最短路1floyd说白了就是个暴力,用三层循环枚举所有路径,然后留下权值最小的一条大概就长这个样for(中转点k) for(起点i) for(终点j) d[i][j]=min(d[i][j],d[i][k]+d[k][j]);注意这个题的数据有重边,输入的时候留下最小的,这样就做完了intd[N][N];voidsolve(){......
  • LeetCode 128.最长连续序列 Python题解
    leetcode128题最长连续序列分享解题思路,使用哈希表算法......
  • 2024年3月10号题解
    299.猜数游戏解题思路对出现的数字在两个数组中进行统计先计算公牛的个数,如果有那么统计的数字的数量对应减一,因为统计是用来算奶牛的数量的遍历统计数组,奶牛的数量加上两个数组中最小的值,因为是匹配,所以不可能多出来的也可以匹配,所以是加上其中的最小值代码实现intmin(i......