AtCoder Beginner Contest 225 English D - Play Train(双链表)

题目描述

题目链接

题目大意

有n个点,每个点的编号为i。有3种,一共m个操作:
1)将y连到x的后面(保证x后面和y前面没有连点)
2)将x-y的连接断开(保证一定存在x-y的连接)
3)输出x所在的链(按顺序输出)

题目分析

pre[x] //记录x的前驱节点,ne[x] //记录x的后继节点

这样我们连接/断开边时都只需要操作pre[]和ne[]数组即可。

输出x所在的链也只需要顺着链表往前和往后遍历即可。

代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iomanip>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PDD pair<double,double>
#define x first
#define y second
using namespace std;
const int N=2e5+5,mod=998244353;
int pre[N],ne[N];
void print(int x)			//输出x所在的链
{
	int p=x;
	vector<int> st,ans;
	while(pre[p]!=p)				//从x开始往前遍历
	{
		st.push_back(pre[p]);
		p=pre[p];
	}
	for(int i=st.size()-1;i>=0;i--) ans.push_back(st[i]);	//将栈中的节点放入ans
	ans.push_back(x); 
	p=x;
	while(ne[p]!=p)				//从x开始往后遍历
	{
		ans.push_back(ne[p]);
		p=ne[p];
	}
	printf("%d ",ans.size());		//输出答案
	for(int it:ans) printf("%d ",it);
	puts("");
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) pre[i]=ne[i]=i;	//初始化
	while(m--)
	{
		int op,x,y;
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d",&x,&y);	//连接x,y
			pre[y]=x;				//让y的前驱等于x
			ne[x]=y;				//让x的后继等于y
		}
		else if(op==2)
		{
			scanf("%d%d",&x,&y);	//断开下x,y
			pre[y]=y;				//让y没有前驱
			ne[x]=x;				//让x没有后继
		}
		else 
		{
			scanf("%d",&x);
			print(x);
		}
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwz_159

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值