题解:使用STL中的list
迭代器的类型是list<Tp>::iterator(这里模板参数Tp需要与你操作的链表一致)。
迭代器的用法和指针有些像,可以用*运算符访问内部的元素,++和--运算符可以将它后移或前移一位(建议写成前置形式),用==和!=运算符进判断两个迭代器所指的位置是否一致。但要注意:list的迭代器不支持it += x或it1 - it2这样的运算,也不支持<,<=等运算符。
begin()成员函数返回指向头部元素的迭代器。
end()成员函数返回指向末尾位置的迭代器。这个“末尾位置”指的是最后一个元素再往后一位,也就是说end()所指的位置不包含有效元素,它相当于一个虚设的节点。这样设计是为了满足C++标准库表示区间时左闭右开的惯例。
insert(it, val)成员函数用于在链表中插入元素。it为该链表的一个迭代器,val为待插入的值,插入后val位于it所指位置的前一位。返回值为一个迭代器,表示val插入到了哪个位置。
remove(it)成员函数用于删除某个迭代器所指的节点。注意在删除之后it就失效了,除非给it重新赋值,否则对它的任何操作都会导致错误!
除上述主要操作以外,list还提供了其他一些实用的成员函数:size()返回链表内元素的个数,empty()判断链表是否为空,remove(val)用于移除所有值为val的节点,以及作为成员函数的sort()和unique()。(注意sort(myList.begin(), myList.end())是错误的写法)
附上代码:
#include<bits/stdc++.h>
using namespace std;
using Iter=list<int>::iterator;
const int maxn=1e5+10;
Iter pos[maxn];
list<int>quelist;
bool erased[maxn];
int n;
void buildqueue()
{
quelist.push_front(1);
pos[1]=quelist.begin();
for(int i=2;i<=n;i++){
int k,p;
scanf("%d%d",&k,&p);
if(p==0){
pos[i]=quelist.insert(pos[k],i);
}else{
auto nextIter=next(pos[k]);
pos[i]=quelist.insert(nextIter,i);
}
}
int m;
scanf("%d",&m);
int x;
for(int i=1;i<=m;i++){
scanf("%d",&x);
if(!erased[x]){
quelist.erase(pos[x]);
}
erased[x]=true;
}
}
int main()
{
scanf("%d",&n);
buildqueue();
bool first=true;
for(list<int>::iterator iter=quelist.begin();iter!=quelist.end();iter++){
if(!first){
printf(" ");
}
first=false;
printf("%d",*iter);
}
printf("\n");
return 0;
}
题解二:模拟链表
题解:使用数组进行模拟链表,和邻接表非常像
//
//#include<bits/stdc++.h>
//
//using namespace std;
//
//using Iter=list<int>::iterator;
//
//const int maxn=1e5+10;
//Iter pos[maxn];
//list<int>quelist;
//bool erased[maxn];
//int n;
//
//void buildqueue()
//{
// quelist.push_front(1);
// pos[1]=quelist.begin();
// for(int i=2;i<=n;i++){
// int k,p;
// scanf("%d%d",&k,&p);
// if(p==0){
// pos[i]=quelist.insert(pos[k],i);
// }else{
// auto nextIter=next(pos[k]);
// pos[i]=quelist.insert(nextIter,i);
// }
// }
// int m;
// scanf("%d",&m);
// int x;
// for(int i=1;i<=m;i++){
// scanf("%d",&x);
// if(!erased[x]){
// quelist.erase(pos[x]);
// }
// erased[x]=true;
// }
//}
//
//int main()
//{
// scanf("%d",&n);
// buildqueue();
// bool first=true;
// for(list<int>::iterator iter=quelist.begin();iter!=quelist.end();iter++){
// if(!first){
// printf(" ");
// }
// first=false;
// printf("%d",*iter);
// }
// printf("\n");
// return 0;
//}
#include<cstdio>
#include<cstring>
int a[100010][3],n,m;
//a[i][2]表示学号为i的同学右边同学的学号
//a[i][3]表示学号为i的同学左边同学的学号
int main()
{
scanf("%d",&n);
int j=1;
memset(a,0,sizeof(a));
a[1][1]=1;
for(int i=2;i<=n;i++)
{
int x,y;
scanf("%d %d",&x,&y);
a[i][1]=i;
if(y==0)
//插入左边
{
a[a[x][3]][2]=i;
a[i][2]=x;
a[i][3]=a[x][3];
a[x][3]=i;
if(x==j) j=i;//最左端
//比较麻烦,要改链表
}
else
//插入右边
{
a[i][2]=a[x][2];
a[a[x][2]][3]=i;
a[x][2]=i;
a[i][3]=x;
}
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
if(a[x][1]!=0)
//该同学还在
{
a[x][1]=0;
//踢掉……(好可怜)
a[a[x][3]][2]=a[x][2];
a[a[x][2]][3]=a[x][3];
n--;
if(x==j) j=a[x][3];
}
}
int i=1,x=j;
while(i<=n)
{
printf("%d ",a[x][1]);
x=a[x][2]; i++;
}
return 0;
}