int ZL_MST(int ROOT)
{
int RTANS = 0;
while (1)
{
for (int i =0 ; i < N; i ++) IN[i] = INF;
for (int i = 0; i < EDGENUMBER;i ++)//m条边
{
int U = EDGE[i].U;int V = EDGE[i].V;
if (U != V && EDGE[i].VALUE < IN[V])//除自环
{
PRE[V] = U;//父亲
IN[V] = EDGE[i].VALUE;//这个点的最小权值
}
}
for (int i = 0; i < N;i ++) if (i != ROOT && IN[i] == INF) return -1;//独立点(不能构成树
int CNT = 0;IN[ROOT] = 0;//cnt新的点
memset(COL, -1, sizeof(COL)); memset(ID, -1, sizeof(ID));//col 染色 id 点编号
for (int i = 0; i < N;i ++)
{
RTANS += IN[i];
int V = i;
while (COL[V] != i && ID[V] == -1 && V != ROOT)
{
COL[V] = i;//向上染色
V = PRE[V];//父亲
}
if (ID[V] == -1 && V != ROOT)//这个父点如果不是根结点的话,并且这个点没被编过号
{
for (int i = PRE[V]; i != V;i = PRE[i]) ID[i] = CNT;
//关于这个点整个树的cnt
ID[V] = CNT ++;
}
}
if (!CNT) break;//如果没有环的话
for (int i = 0; i < N;i ++) if (ID[i] == -1) ID[i] = CNT ++;
for (int i = 0; i < EDGENUMBER;i ++)
{
int V = EDGE[i].V;
EDGE[i].U = ID[EDGE[i].U];
EDGE[i].V = ID[EDGE[i].V];
if (EDGE[i].U != EDGE[i].V) EDGE[i].VALUE -= IN[V];//减去环中不需要的权值
}
N = CNT;//n为缩过的点
ROOT = ID[ROOT];//根结点要变
}
return RTANS;
}