图
定义
#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
------------恢复内容结束------------