#include<iostream>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
#define OK 1
#define ERROR 0
#define Status int
#define inf 0x3f3f3f3f
typedef struct arc
{
int v0;
int v1;
int cost;
}arc;
vector<arc> g;
vector<int> branch;
int sum_cost=0;//最小权值
bool cmp(arc a, arc b)
{
return a.cost > b.cost;//排序,最小权值的边在末尾
}
void cout_branch_state()
{
cout << "当前branch数组状态为:";
for (int i = 1; i < branch.size(); i++)
{
cout << branch[i]<<" ";
}
cout << endl;
}
int main()
{
int n, e;
cin >> n >> e;//顶点数和边数 顶点从1--n编号
branch.resize(n + 1);
g.resize(e);
for (int i = 1; i <= n; i++)
{
branch[i] = i;
}
for (int i = 0; i < e; i++)
{
cin >> g[i].v0 >> g[i].v1 >> g[i].cost;
}
sort(g.begin(), g.end(), cmp);
for (int i = 1; i <= n-1; i++)//找到n-1条边和n个顶点构成最小生成树
{
while (g.size())//找到一条符合条件的可插入的边
{
arc temp;
temp = g.back();
if (branch[temp.v0] == branch[temp.v1])//属于同一连通分支,加入该边会形成圈,应舍弃
{
g.pop_back();
}
else
{
g.pop_back();
//将所有和v1处于相同连通分支的节点的连通分支序号变成和v0的连通分支序号相同
cout_branch_state();
int want_change = branch[temp.v1];//记录要改变的连通分支序号
for (int k = 1; k <= n; k++)
{
if (branch[k] == want_change)
branch[k] = branch[temp.v0];
}
cout <<" 加入的边为: "<< temp.v0 << " " << temp.v1 << " " << temp.cost << endl;
cout_branch_state();
sum_cost += temp.cost;
break;
}
}
}
int last_branch_id=branch[1];
for (int i = 2; i <= n; i++)
{
if (branch[i] != last_branch_id)//若所给图不连通,最终结果存在不同连通分支,则输出-1
{
cout << -1;
return 0;
}
}
cout << sum_cost;
return 0;
}
同样,此方法还可以用于判断无向图的两个顶点之间是否存在路径,如题
#include<iostream>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
#define OK 1
#define ERROR 0
#define Status int
#define inf 0x3f3f3f3f
int main()
{
int n, e,start,end;
cin >> n >> e;
vector<int> graph;
graph.resize(n);
int index = 1;
for (auto& d : graph)
{
d = index++;
}
for (int i = 1; i <= e; i++)
{
int x, y;
cin >> x >> y;
if (graph[x] != graph[y])
{
int temp = graph[y];
for (auto& d : graph)
{
if (d == temp) d = graph[x];
}
}
}
cin >> start >> end;
if(graph[start]==graph[end])
cout << "There is a path between " << start << " and " << end << ".";
else
cout<< "There is no path between " << start << " and " << end << ".";
return 0;
}
即: