Stacks
VJ链接
题意:
初始给定
n
n
n 个栈,第
i
i
i 个栈的初始元素为
i
i
i
m
m
m 次操作,每次把栈
a
i
a_i
ai 里的全部元素放到栈
b
i
b_i
bi
操作的过程:从
a
i
a_i
ai 的栈顶开始每
p
o
p
pop
pop 一个元素就加入
b
i
b_i
bi 栈
操作完后输出每个栈的元素(从栈顶到栈底的顺序
思路:
题解
注意到操作其实只是将栈链接起来了,并不需要去模拟真正的这个操作过程
考虑建图
结构体的
l
,
r
l,r
l,r 作为栈的顶和底
每次修改其实就是两个栈链接起来
然后分类讨论
如果两个栈都非空,就给链接点建图并修改栈顶
如果
a
a
a 非空,
b
b
b 空,那么就直接把
a
a
a 栈倒过来赋给
b
b
b 就好了
code:
#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N = 1e5 + 10;
struct node
{
int l, r;
} q[N];
int n, m, k;
int ans[N];
vector<int>e[N];
void dfs(int u, int f)
{
ans[++k] = u;
for (int v : e[u])
{
if (v == f)continue;
dfs(v, u);
}
}
int main()
{
ios::sync_with_stdio(0);
while (cin >> n >> m)
{
for (int i = 1; i <= n; ++i) q[i].l = q[i].r = i, e[i].clear();
while (m--)
{
int a, b;cin >> a >> b;
if (q[a].l && q[b].l) // a, b 非空
{
e[q[a].l].push_back(q[b].l);
e[q[b].l].push_back(q[a].l);// 建一个无向图
q[b].l = q[a].r;// 将
q[a].l = q[a].r = 0;
}
else if (q[a].l && !q[b].l) // a非空,b空
{
q[b].l = q[a].r;
q[b].r = q[a].l;
q[a].l = q[a].r = 0;
}
}
for (int i = 1; i <= n; ++i)
{
if (!q[i].l) cout << "0\n";
else
{
k = 0;
dfs(q[i].l, -1);
cout << k;
for (int i = 1; i <= k; ++i) cout << " " << ans[i];
cout << "\n";
}
}
}
return 0;
}
本文探讨了如何通过图论思想解决涉及多个栈操作的问题,重点在于理解操作的实质并利用结构化建图,处理栈间链接和元素转移。通过代码实现,展示了如何在O(n)时间内处理n个栈的m次操作,输出各栈最终元素序列。
1856

被折叠的 条评论
为什么被折叠?



