#include <iostream>
#include <cstdio>
#define Max 1000
#define Inf 1000000
using namespace std;
int G[Max][Max];//图的邻接矩阵
bool use[Max];//标记C_1集合与C_2集合
int V,E;
int sum;//最小生成树的权值之和
int pre[Max];//记录路径
int mindist[Max];//记录最小距离
void prime()
{
sum=0;
for(int i=0; i<V; i++) //初始化
{
pre[i]=-1;
use[i]=true;
mindist[i]=Inf;
}
mindist[0]=0;
for(int i=0; i<V; i++)
{
int Min=-1;
for(int j=0; j<V; j++)//选取最短距离
if(use[j]&&(Min==-1||mindist[Min]>mindist[j]))
Min=j;
if(Min==-1)
break;
sum+=mindist[Min];
use[Min]=false;
for(int j=0;j<V;j++)//更新最短距离
{
if(use[j]&&(mindist[j]>G[Min][j]))
{
mindist[j]=G[Min][j];
pre[j]=Min;
}
}
}
}
int main()
{
scanf("%d%d",&V,&E);
for(int i=0; i<V; i++)
for(int j=0; j<V; j++)
if(i==j)
G[i][j]=0;
else
G[i][j]=Inf;
int a,b,c;
for(int i=0; i<E; i++)
{
scanf("%d%d%d",&a,&b,&c);
G[a][b]=G[b][a]=c;
}
prime();
printf("\n%d\n",sum);
for(int i=0;i<V;i++)
printf("%d——>%d\n",i,pre[i]);
return 0;
}
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#define Max 1000
#define Inf 1000000
using namespace std;
struct edge
{
int to;
int value;
friend bool operator<(edge a,edge b)
{
return a.value>b.value;
}
};
vector<edge> G[Max];//邻接链表
int V,E;//顶点与边数
bool use[Max];//标记数组
int sum;//最小生成树的权值
int pre[Max];//记录每个点在前驱
int d[Max];//记录最短距离数组
void prime()
{
for(int i=0;i<V;i++)
{//初始化
use[i]=true;
pre[i]=-1;
d[i]=Inf;
}
edge x,y;
d[0]=0;//从0点开始
x.to=0;
x.value=0;
priority_queue<edge> Que;//优先队列
Que.push(x);
while(!Que.empty())
{
x=Que.top();//取出最短距离
Que.pop();
if(use[x.to])
{
sum+=x.value;
use[x.to]=false;
for(int i=0;i<G[x.to].size();i++)//更新其他点的最短距离
{
y=G[x.to][i];
if(use[y.to]&&d[y.to]>y.value)
{
d[y.to]=y.value;
pre[y.to]=x.to;
Que.push(y);
}
}
}
}
}
int main()
{
scanf("%d%d",&V,&E);
int a,b,c;
edge x,y;
for(int i=0; i<E; i++)
{
scanf("%d%d%d",&a,&b,&c);
x.to=a;
y.to=b;
x.value=y.value=c;
G[a].push_back(y);
G[b].push_back(x);
}
prime();
printf("%d\n",sum);
for(int i=0;i<V;i++)
printf("%d——>%d\n",i,pre[i]);
return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#define Max 1000
#define Inf 10000000
using namespace std;
struct edge//边的结构体
{
int point_1;
int point_2;
int value;
friend bool operator< (const edge& a,const edge& b)//重载运算符<,因为sort使用该运算符
{
return a.value<b.value;
}
};
edge G[Max];//边集表示图
int V,E;//顶点数和边数
int Set[Max];//图顶点的并查集
int high[Max];//并查集树高
int sum;//最小生成树的权值
int MST[Max];//最小生成树的边集
int M;
void init(int n)//并查集初始化
{
for(int i=0; i<n; i++)
{
Set[i]=i;
high[i]=1;
}
}
int Find(int x)//查找x的根节点
{
if(Set[x]==x)
return x;
else
return Set[x]=Find(Set[x]);//路径压缩
}
void conbine(int x,int y)//合并x和y的集合
{
int R_1=Find(x);
int R_2=Find(y);
if(R_1==R_2)
return;
if(high[R_1]>high[R_2])
Set[R_2]=R_1;
if(high[R_2]>high[R_1])
Set[R_1]=R_2;
if(high[R_1]==high[R_2])
{
Set[R_2]=R_1;
high[R_1]++;
}
}
bool same(int x,int y)//判断x与y是否在同一个集合
{
return Find(x)==Find(y);
}
void krustra()
{
init(V);
sort(G,G+E);
sum=0;
int x,y;
M=0;
for(int i=0; i<E; i++)
{
x=G[i].point_1;
y=G[i].point_2;
if(!same(x,y))
{
//printf("%d\n",i);
MST[M++]=i;
conbine(x,y);
sum+=G[i].value;
}
}
}
int main()
{
scanf("%d%d",&V,&E);
for(int i=0; i<E; i++)
scanf("%d%d%d",&G[i].point_1,&G[i].point_2,&G[i].value);
krustra();
printf("%d\n",sum);
for(int i=0; i<M; i++)
printf("%d %d %d\n",G[MST[i]].point_1,G[MST[i]].point_2,G[MST[i]].value);
return 0;
}