转载:https://blog.csdn.net/yueshehanjiang/article/details/117717599
题目:Stacks
题意:
有n个栈,编号从1到n,初始栈内只有元素 i ,
现给出m条操作,每条操作a,b,
a,b表示栈a中元素放入到栈b中(先进后出原则).
最后输出每个站内元素数量和元素(从顶到底输出).
题解:
n,m范围1e5,模拟过程必定超时.
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e5+1100;
int first[N],nx[N*2],to[2*N],head;
int d[N],k;
struct Node{
int top,bot;//栈的顶部和底部
}q[N];
void add(int x,int y)
{
nx[head]=first[x];
first[x]=head;
to[head++]=y;
}
void dfs(int x,int fa)
{
for(int i=first[x];i!=-1;i=nx[i])
{
int j=to[i];
if(j==fa) continue;
d[++k]=j;
dfs(j,x);
}
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
head=1;
memset(first,-1,sizeof(first));
for(int i=1;i<=n;i++)
q[i].top=q[i].bot=i;
while(m--)
{
int a,b;
scanf("%d %d",&a,&b);
if(q[a].top&&q[b].top)
{
add(q[a].top,q[b].top);
add(q[b].top,q[a].top);
q[b].top=q[a].bot;
q[a].top=q[a].bot=0;
}
else if(q[a].top&&!q[b].top)
{
q[b].top=q[a].bot;
q[b].bot=q[a].top;
q[a].top=q[a].bot=0;
}
}
for(int i=1;i<=n;i++)
{
if(!q[i].top)
printf("0\n");
else
{
k=0;
d[++k]=q[i].top;
dfs(q[i].top,-1);
printf("%d",k);
for(int j=1;j<=k;j++)
printf(" %d",d[j]);
printf("\n");
}
}
}
return 0;
}