题目分析
简单的最小生成树的题目,首先这道题我超时了n次,但是因此也知道了,当图为稠密图的时候需要注意是否超时,改进了之后982ms险过,但是用prim的话时间复杂度低一点,因此大家要注意。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int fa[505], a[505];
struct Edge
{
int from,to,cost;
bool operator < (const Edge temp) const
{
return cost < temp.cost;
}
}e[25005];
int Find(int x)
{
if(fa[x] == x) return fa[x];
fa[x] = Find(fa[x]);
return fa[x];
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n,m,k,cnt;
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++)
fa[i] = i;
for(int i = 0; i < m; i++)
scanf("%d%d%d", &e[i].from,&e[i].to,&e[i].cost);
int flag = n-1;
while(k--)
{
scanf("%d", &cnt);
for(int i = 0; i < cnt; i++)
scanf("%d", &a[i]);
int xx = Find(a[0]);
for(int i = 1; i < cnt; i++)
{
int yy = Find(a[i]);
if(xx != yy)
{
fa[yy] = xx;
flag--;
}
}
}
sort(e, e+m);
int ans = 0;
for(int i = 0; i < m && flag > 0; i++)
{
int xx = Find(e[i].from);
int yy = Find(e[i].to);
if(xx != yy)
{
fa[yy] = xx;
flag--;
ans += e[i].cost;
}
}
if(flag) printf("-1\n");
else printf("%d\n", ans);
}
return 0;
}