UVALive 7752 Free Figurines——双向链表

来源:互联网 发布:电子商务模式价值网络 编辑:程序博客网 时间:2024/05/29 04:41

题目要求用最少的步数达到目标,所以要从最小的娃娃开始处理,即从1开始,最后处理到n;

然后就是用双向链表模拟,模拟父子关系的连接与断开,假设要把a连接到b,那么首先把a b的所有父节点断开,然后断开b的一个子节点。

写的时候写乱了,把par和son链表的结束标志都设为0了, 导致0的子节点连接到了7之类的错误,这个特判一下就好

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 1e5 + 10;int N, a[MAXN], b[MAXN], par[MAXN], son[MAXN], ans;void DeleteSon(int x) {    for (int i = par[x]; i; i = par[i]) {        //cout << "Delete " << i << " s son" << endl;        son[i] = 0;        ans++;    }}void DeletePar(int x) {    if (par[x] == 0) return;    DeletePar(par[x]);    //cout << "Delete " << x << " s par" << endl;    par[x] = 0;}int main() {    while (~scanf("%d", &N)) {        memset(par, 0, sizeof(par));        memset(son, 0, sizeof(son));        for (int i = 1; i <= N; i++) {            scanf("%d", &a[i]);            par[i] = a[i];            son[a[i]] = i;        }        ans = 0;        for (int i = 1; i <= N; i++) {            scanf("%d", &b[i]);            if (par[i] == b[i]) continue;            //cout << i << " to " << b[i] << " : " << endl;            DeleteSon(i); DeletePar(i);            DeleteSon(b[i]); DeletePar(b[i]);            if (b[i]) {                if (son[b[i]]) {                   int temp = son[b[i]];                    //cout << "Delete " << temp << " s par and " << b[i] << " s son" << endl;                    par[temp] = 0;                    son[b[i]] = 0;                    ans++;                }                par[i] = b[i];                son[b[i]] = i;                ans++;            }        }        printf("%d\n", ans);    }    return 0;}