码迷,mamicode.com
首页 > 其他好文 > 详细

「CF650E」Clockwork Bomb

时间:2019-10-27 10:59:47      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:gis   inline   参考   print   struct   for   etc   ctime   while   

传送门
Luogu

解题思路

显然对于两棵树共有的边,我们不会动它。
考虑第二颗树中有和第一棵树不同的边怎么处理。
我们设 \(fa_1[u],fa_2[u]\) 分别代表 \(u\) 在两棵树中的父亲。
很显然的想法就是对于第一棵树中的边 \(fa_1[u] \rightarrow u\) 没有出现在第二棵树上,那就把这条边换成 \(fa_2[u] \rightarrow u\)
但是我们会发现有可能 \(fa_2[u] \rightarrow u\) 已经被连上了。
那么我们就尝试跳 \(fa_2[u]\) 的父亲知直到可以连边,这个过程可以用一个并查集来搞(预处理出每个点会连向哪个点)。
并且在dfs的过程中先处理子树信息,可以保证不会连出环。

细节注意事项

  • 咕咕咕

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <vector>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int _ = 500000 + 10;

int n, ff[2][_], fa[_];
vector < int > G[2][_];
struct node{ int a, b, c, d; };
vector < node > ans;

inline int findd(int x) { return fa[x] == x ? x : findd(fa[x]); }

inline void dfs(int x, int u, int f) {
    for (rg int v : G[x][u]) {
        if (v == f) continue;
        ff[x][v] = u, dfs(x, v, u);
    }
}

inline void dfss(int u, int f) {
    for (rg int v : G[0][u]) {
        if (v == f) continue; dfss(v, u);
        if (u != ff[1][v] && v != ff[1][u])
            ans.push_back((node) { v, u, findd(v), ff[1][findd(v)] });
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    read(n);
    for (rg int u, v, i = 1; i < n; ++i) read(u), read(v), G[0][u].push_back(v), G[0][v].push_back(u);
    for (rg int u, v, i = 1; i < n; ++i) read(u), read(v), G[1][u].push_back(v), G[1][v].push_back(u);
    dfs(0, 1, 0);
    dfs(1, 1, 0);
    for (rg int i = 2; i <= n; ++i) {
        int u = ff[1][i];
        if (u == ff[0][i] || i == ff[0][u])
            fa[i] = u;
        else
            fa[i] = i;
    }
    dfss(1, 0);
    printf("%d\n", (int) ans.size());
    for (rg node x : ans) printf("%d %d %d %d\n", x.a, x.b, x.c, x.d);
    return 0;
}

完结撒花 \(qwq\)

「CF650E」Clockwork Bomb

标签:gis   inline   参考   print   struct   for   etc   ctime   while   

原文地址:https://www.cnblogs.com/zsbzsb/p/11746539.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!