定义

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100+10;

struct Edge {
    int from;
    int to;
    int length;
    Edge(int f,int t,int l):from(f),to(t),length(l){}
    bool operator< (Edge e) const {
        return length<e.length;
    }
};

 

无向图、有向图的构造

vector<Edge> graph[MAXN];

//无向图
void NoDirectionInitial(int n) {    //n条边
    int from,to,length;
    while (n--) {    //n表示边数
        Edge p1(from,to,length);
        graph[from].push_back(p1);
        Edge p2(to,from,length);
        graph[to].push_back(p2);
    }
}

//有向图
void DirectionInitial(int n) {    //n条边
    int from,to,length;
    while (n--) {
        Edge p(from,to,length);
        graph[from].push_back(p);
    }
}

 

并查集

int root[MAXN];
int height[MAXN];    //height只对根节点有意义,表示的是其子树的最长长度(注意是“最长”)

//初始化
void Initial(int n) {
    for (int i=0;i<n;i++) {
        root[i] = i;
        height[i] = 0;
    }
}

//查(查找根节点),顺便将其父节点直接指向其根节点
int Find(int i) {
    if (i!=root[i]) {
        root[i] = Find(root[i]);
    }
    return root[i];
}

//并(小树并在大树下)
void Union(int x,int y) {
    x = Find(x);
    y = Find(y);
    if (x==y) {
        return ;
    }
    else {
        if (height[x]>height[y]) {
            root[y] = x;
        }
        else if (height[x]<height[y]){
            root[x] = y;
        }
        else {
            root[x] = y;
            height[y]++;
        }
    }
}

 

 

最小生成树(Kruskal)(利用并查集)

 

priority_queue<Edge,vector<Edge>,greater<Edge>> edge;    //构建小根堆,自动将第一个值为最小
int Kruskal(int n,int m) { //输入n个顶点,m条边,返回最小生成树的权值 Initial(n); //初始化,让每个点都各自为阵 int sum = 0; for (int i=0;i<m;i++) { Edge e = edge.top(); if (Find(e.from)!= Find(e.to)) { //如果首尾都还没有连接过 Union(e.from,e.to); //就算是两个独立的结点,也能因为这条边而使得根节点一样了 sum += e.length; } edge.pop(); //如果处理完,或者首位已经在同一个树中,则弹出,继续处理下一个 } return sum; } int main() { int n,m; cin >> n >> m; for (int i=0;i<m;i++) { int from,to,length; cin >> from >> to >> length; Edge e(from,to,length); edge.push(e); } cout << Kruskal(n,m) << endl; return 0; }

 

最大连通数(利用并查集)

int ConnectGraph(int n) {
    int sum;
    for (int i=0;i<n;i++) {
        if (i==Find(i)) {   //在此之前只有并操作,还没有更新find操作
            sum++;
        }
    }
    return sum;
}

int main() {
    int n,m;
    cin >> n >> m;
    Initial(n);
    for (int i=0;i<m;i++) {
        int from,to;
        cin >> from >> to;
        Union(from,to);
    }
    cout << ConnectGraph(n) << endl;
    return 0;
}

 

DFS

 

BFS

DFS

 

 

 

 

------------恢复内容结束------------

posted @ 2022-03-10 22:00  火星架构师  阅读(44)  评论(0)    收藏  举报