题意:
连通一个图,找最小权值和,有重边
要点:
因为有重边,所以Prim算法还要取最小的边加入,而Kruskal算法可以直接忽略这个问题,因为一开始要排序,大的自动舍掉了。这题很水,但我WA了快1个小时,原因init函数中,因为我是从0开始到n-1的,这题因为卡的比较紧,数据是从1~n的,所以这里少了一个数值一直WA,以后要注意这个地方。
15345730 | Seasonal | 1287 | Accepted | 188K | 16MS | C++ | 870B | 2016-04-02 20:55:59 |
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct edge
{
int u, v, len;
}e[5100];
int p[5100];
int n,m;
bool cmp(edge a, edge b)
{
return a.len < b.len;
}
void init()
{
for (int i = 1; i <= n; ++i)//题目数据是从1~n的
p[i] = i;
}
int find(int x)
{
if (p[x] == x) return x;
return p[x] = find(p[x]);
}
bool merge(int x, int y)
{
x = find(x);
y = find(y);
if (x != y)
{
p[y] = x;
return true;
}
return false;
}
void kruskal()
{
init();
sort(e, e + m, cmp);
int edges = 0,sum=0;
for (int i = 0; i < m; ++i)
{
if (merge(e[i].u, e[i].v))
{
sum += e[i].len;
edges++;
}
if (edges + 1 == n)
break;
}
printf("%d\n", sum);
}
int main()
{
while (scanf("%d", &n)==1&&n)
{
scanf("%d", &m);
for (int i = 0; i < m;++i)
{
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].len);
}
kruskal();
}
return 0;
}