#include <stdio.h>
#define MAX 20
typedef struct
{
char Shi, Mo; //边的起始点
int weight; //边的权值
}Edge;
typedef struct
{
char Ding[MAX]; //存放顶点信息
Edge edge[MAX]; //存放边的信息
int dingnum, biannum; //顶点数,边数
}EdgeGraph;
void Create(EdgeGraph* M)
{
scanf("%d %d", &M->dingnum, &M->biannum); //输入顶点数,弧数
for (int i = 0; i < M->dingnum; i++) //输入顶点的值
scanf("%c", &M->Ding[i]);
for (int i = 0; i < M->biannum; i++) { //输入每条边的始末,权值
scanf("(%c,%c,%d)", &M->edge[i].Shi, &M->edge[i].Mo, &M->edge[i].weight);
}
}
void Pai(EdgeGraph* M) //利用冒泡排序,将每条边按权值由小到大排序
{
for (int i = 0; i < M->biannum - 1; i++)
for (int j = i + 1; j < M->biannum; j++) {
if (M->edge[i].weight > M->edge[j].weight) {
Edge temp = M->edge[i];
M->edge[i] = M->edge[j];
M->edge[j] = temp;
}
}
}
int Findding(EdgeGraph* M, char ding) //寻找当前顶点在顶点数组中的下标
{
for (int i = 0; i < M->dingnum; i++) {
if (ding == M->Ding[i])
return i;
}
return -1;
}
int FindRoot(int t, int parent[]) //寻找当前结点的根节点
{
while (parent[t] > -1)
t = parent[t];
return t;
}
void Kruskal(EdgeGraph* M)
{
int num=0;
int root1, root2; //第一个顶点与第二个顶点的根结点
int ding1, ding2;
int parent[MAX];
Pai(M);
for (int i = 0; i <= M->dingnum; i++) //初始化每个根节结点
parent[i] = -1;
for (int i = 0; i < M->biannum; i++) {
ding1 = Findding(M, M->edge[i].Shi); //找到起始点在数组中下标
ding2 = Findding(M, M->edge[i].Mo); //找到末尾点在数组中下标
root1 = FindRoot(ding1, parent); //通过下标,求该结点的根节点
root2 = FindRoot(ding2, parent);
if (root1 != root2) { //若根节点不同,则输出,且num++
printf("(%c,%c,%d,1)", M->edge[i].Shi, M->edge[i].Mo, M->edge[i].weight);
parent[root2] = root1; //连接两个结点
num++;
}
else
printf("(%c,%c,%d,0)", M->edge[i].Shi, M->edge[i].Mo, M->edge[i].weight);
if (num == M->dingnum - 1) { //当已经连接的边数=顶点数-1时,结束算法
while (i<biannum){ //输出剩下的边
i++;
printf("(%c,%c,%d,0)", M->edge[i].Shi, M->edge[i].Mo, M->edge[i].weight);
}
return ;
}
}
}
main()
{
EdgeGraph* M = (EdgeGraph*)malloc(sizeof(EdgeGraph));
Create(M);
Kruskal(M);
}