吐槽:
昨晚一点多的时候写,老是错,老是调试,调了很久还是没调试出来,唉,太久没写过,都这么菜了,早上10点多大脑清醒,重新写了一遍,就1a了,还是早睡早起来写代码好点儿。
题目大意:
经典的畅通工程,再经典不过的并查集了。很久以前用prim写过,这次换换并查集,果然,并查集思路还是简单一点啊。
解题思路;
用并查集写kruscal.
代码:
#include
#include
using namespace std;
const int MAXV = 105;
const int MAXE = 10005;
typedef struct node
{
int u, v, w;
}N;
typedef struct set
{
int parent;
int rank;
}S;
S set[MAXV];
//int father[MAXV];
N node[MAXE];
bool cmp(N a, N b)
{
return a.w < b.w;
}
void makeSet()
{
for(int i = 0; i < MAXV; i++)
set[i].parent = i;
}
int findParent(int x)
{
if(x != set[x].parent)
set[x].parent = findParent(set[x].parent);
return set[x].parent;
}
bool Union(int a, int b)
{
a = findParent(a);
b = findParent(b);
if(a == b)
return false;
if(set[a].rank > set[b].rank)
set[b].parent = a;
else
{
set[a].parent = b;
if(set[a].rank == set[b].rank)
set[b].rank++;
}
return true;
}
int main(void)
{
int n, m;
while(scanf("%d %d", &n, &m), n)
{
for(int i = 1; i <= n; i++)
scanf("%d %d %d", &node[i].u, &node[i].v, &node[i].w);
sort(node+1, node+n+1, cmp);
makeSet();
int sum = 0;
for(int i = 1; i <= n; i++)
{
if(Union(node[i].u, node[i].v) == true)
sum += node[i].w;
}
int sumT = 0;
for(int i = 1; i <= m; i++)
{
if(set[i].parent == i)
sumT++;
}
if(sumT != 1)
printf("?\n");
else
printf("%d\n", sum);
}
return 0;
}