day56 第十一章:图论part06

108.冗余连接

注意init初始化

改进:

其实只有一条边冗余,改为,如果两条边在同一个集合里,就输出,不然加入。

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int n = 1005;
vector<int> father(n,0);

void init(){
    for (int i=0;i<n;i++){
        father[i] = i;
    }
}

int find(int u){
    return u == father[u]? u: father[u] = find(father[u]);
}

bool isSame(int u, int v){
    u = find(u);
    v =  find(v);
    return u == v;
}

void join(int u, int v){
    u = find(u);
    v = find(v);
    if(u==v){
        return;
    }
    father[u] = v;
}

int main(){
    
    int N;
    cin >>N;
    init(); //1111

    int s,t,redun_s, redun_t;
    bool result;
    while(N--){
        cin>>s>>t;
        result = isSame(s,t);
        if (result){
            redun_s = s;
            redun_t = t;
        }
        join(s,t);
    }
    cout << redun_s <<" "<< redun_t << endl;
    
    
    return 0;
}

109.冗余连接II

不好做:

1.入度为2:看删哪条边可以形成树,而不是环(因为只有两种可能,一个树,一个环)

2.没有入度为2的点:有向环,删最后形成环的那条

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int n;
vector<int> father(1001, 0);

void init() {
    for (int i = 0; i < n; i++) {
        father[i] = i;
    }
}

int find(int u) {
    return u == father[u] ? u : father[u] = find(father[u]);
}

bool isSame(int u, int v) {
    u = find(u);
    v = find(v);
    return u == v;
}

void join(int u, int v) {
    u = find(u);
    v = find(v);
    if (u == v) {
        return;
    }
    father[v] = u;
}

bool isTreeAfterRemoveVec(const vector<vector<int>>& edges, int v) {
    init();
    for (int i = 0; i < n; i++) {
        if (i == v) {
            continue;
        }
        if (isSame(edges[i][0], edges[i][1])) {
            return false;
        }
        join(edges[i][0], edges[i][1]);
    }

    return true;
}

void getRemoveEdge(const vector<vector<int>>& edges) {
    init();
    for (int i = 0; i < n; i++) {
        if (isSame(edges[i][0], edges[i][1])) {
            cout << edges[i][0] << " " << edges[i][1];
            return;
        }
        join(edges[i][0], edges[i][1]);
    }
}

int main() {

    // int N;
    cin >> n;
    // init(); //1111
    
    // n = 3;
    // vector<vector<int>> grid;
    // grid = {
    //     {1,2},
    //     {1,3},
    //     {2,3}
    // };


    vector<vector<int>> edges;
    vector<int> degrees(n+1, 0);

    int s, t;
    for(int i=0;i<n;i++) {
        cin >> s >> t;
        // s = grid[i][0];
        // t = grid[i][1];

        edges.push_back({ s,t });
        degrees[t]++;

    }

    //计算入度
    vector<int> vec;
    for (int i = 0; i < n; i++) {
        //cout << degrees[edges[i][1]] << " ";
        if (degrees[edges[i][1]] == 2) {
            vec.push_back(i);
        }
    }
    
    //情况1:入度为2,看删哪个
    if (vec.size() > 1) {
        if (isTreeAfterRemoveVec(edges, vec[1])) {
            cout << edges[vec[1]][0] << " " << edges[vec[1]][1] << endl;
        }
        else {
            cout << edges[vec[0]][0] << " " << edges[vec[0]][1] << endl;
        }
        return 0;
    }

    //情况2:有向环
    getRemoveEdge(edges);

    return 0;
}
相关推荐
王老师青少年编程5 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:雷达安装
c++·算法·贪心·csp·信奥赛·区间贪心·雷达安装
elseif1236 分钟前
分组背包1
c++·学习·算法
im_AMBER10 分钟前
Leetcode 160 最小覆盖子串 | 串联所有单词的子串
开发语言·javascript·数据结构·算法·leetcode
Rabitebla12 分钟前
【数据结构】动态顺序表实现详解:从原理到接口设计(面试视角)
c语言·开发语言·数据结构·c++·面试·职场和发展
狐璃同学13 分钟前
数据结构(1)三要素
数据结构·算法
小明同学0115 分钟前
[C++入门]万字长文梳理 C++11 核心特性
c++
列星随旋19 分钟前
拓扑排序(Kahn算法)
算法
郝学胜-神的一滴21 分钟前
Linux 高并发基石:epoll 核心原理 + LT/ET 触发模式深度剖析
linux·运维·服务器·开发语言·c++·网络协议
Hello!!!!!!27 分钟前
C++基础(六)——数组与字符串
c++·算法
山半仙xs33 分钟前
基于卡尔曼滤波的人脸跟踪
人工智能·python·算法·计算机视觉