zoukankan      html  css  js  c++  java
  • 生成树


    你有一张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
  • 相关阅读:
    Leetcode665.Non-decreasing Array非递减数组
    在MyEclipse中把多行代码用一快捷键注释掉
    struts2中addFieldError()方法
    [bzoj2588][Spoj10628]Count on a tree_主席树
    [bzoj3123][Sdoi2013]森林_主席树_启发式合并
    [bzoj1500][NOI2005]维修数列_非旋转Treap
    [bzoj1452][JSOI2009]Count_树状数组
    [bzoj1369][Baltic2003]Gem_树形dp_结论题
    [bzoj1195][HNOI2006]最短母串_动态规划_状压dp
    [bzoj2242][Sdoi2011]计算器_exgcd_BSGS
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/13423125.html
Copyright © 2011-2022 走看看