这题用两个数组记录删除后的链表当前节点地址和下一个地址是一个不错的思路。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string.h> #include <cstdio> #include <algorithm> #include <cstdlib> #include <math.h> #include <queue> #include <vector> #define maxn 100005 #define INF 0x3f3f3f3f using namespace std; typedef long long ll; struct node { int nextadr; int nkey; }no[maxn]; int s,n,adr,key,nadr; int del[maxn],vis[maxn],fir[maxn],sec[maxn]; int main() { scanf("%d%d",&s,&n); for(int i=0;i<n;i++) { scanf("%d%d%d",&adr,&key,&nadr); no[adr].nextadr=nadr; no[adr].nkey=key; } int p=0,q=0; int ta=s; int tk=no[s].nkey; int tn=no[s].nextadr; if(tn==-1) { printf("%05d %d -1\n",ta,no[ta].nkey); return 0; } for(int i=0;i<n;i++) { if(!vis[abs(tk)]) { vis[abs(tk)]=1; fir[p]=ta; sec[p]=no[ta].nextadr; p++; } else { del[q++]=ta; sec[p-1]=tn; } if(tn==-1) { sec[p-1]=-1; break; } ta=no[ta].nextadr; tk=no[ta].nkey; tn=no[ta].nextadr; } for(int i=0;i<p;i++) { if(sec[i]==-1) printf("%05d %d -1\n",fir[i],no[fir[i]].nkey); else printf("%05d %d %05d\n",fir[i],no[fir[i]].nkey,sec[i]); } for(int i=0;i<q-1;i++) { printf("%05d %d %05d\n",del[i],no[del[i]].nkey,del[i+1]); } printf("%05d %d -1\n",del[q-1],no[del[q-1]].nkey); return 0; }