生成树


你有一张n个点的完全图(即任意两点之间都有无向边)
现在给出这张图的两棵生成树
定义一次操作为:在任意一棵生成树中删除一条边后再加入一条边(必须在同一棵树中操作),同时需要保证操作完后仍然是一棵树

问使得两棵树相同的最少操作次数,若不存在合法的操作方案,输出-1

注意:这里的相同指的是点集与边集均相同,也就是对于第一棵树中的边(u, v),第二棵树中一定存在边(u, v)或(v, u),再不懂请看样例解释。

输入描述:

一个整数n表示无向图的点数
接下来n - 1行,每行两个整数u, v表示第一棵生成树中的边
再接下来n - 1行,每行两个整数u, v表示第二棵生成树中的边

输出描述:

一个整数,表示最少操作次数


思路:
刚看到这个题的时候,花了一个图,然后想到找不同的边数

都是n - 1条边,假设有x条不同的边,说明这x条边都要删了然后加上x条边

反过来,n - 1 - 相同的边数也是本题答案

大佬的代码,太棒了
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
struct node {
    int x, y;
    bool operator<(const node& a) const {//不是内置类型,需要重载
        if (x != a.x) return x < a.x;
        else return y < a.y;
    }
};
int main() {
    set<node> v;
    int n;
    cin >> n;
    int xx,yy;
    for (int i = 0; i < n - 1; i++) {
        cin >> xx >> yy;
        if (xx > yy) swap(xx, yy);
        v.insert(node{xx,yy});
    }
    /*for (auto i : v) {//可以输出观察一下
        cout << i.x << " "<<i.y<< endl;
    } */
    int ans = v.size();
    for (int i = 0; i < n - 1; i++) {
        cin >> xx >> yy;
        if (xx > yy) swap(xx, yy);
        v.insert(node{xx,yy});
    }
    cout << v.size() - ans << endl;
    /*for (auto i : v) {//可以输出观察一下
        cout << i.x << " "<<i.y<< endl;
    } */
}
View Code

 

posted @ 2020-08-02 20:57  Hazelxcf  阅读(328)  评论(0编辑  收藏  举报