UVA908 题解
题目大意
此题有多组数据,且不会告诉你数据组数。(一开始我没看到,WA 了半天)
分两部分处理。
- 第一部分:
给你一个有
- 第二部分:
不管前
前置知识
很明显,是 最小生成树 。
推荐板子题:P3366【模板】最小生成树 。
具体思路
我们先看第一部分:
很明显,
第二部分:就是一个最小生成树板子,这里使用 Kruskal 实现。
实现
坑点:
-
在最后一组数据读完后不能有多余换行(我也不知道为什么)。
-
多测要清空。
代码:
#include<bits/stdc++.h>
#define Max 1000005
using namespace std;
struct edge{
int u,v,w;
}g[Max];
int fa[Max],n,m,ans;
int a,b,c,cnt,k,cacnt;
bool cmp(edge x,edge y){
return x.w<y.w;
}
int find(int x){
if(x!=fa[x]) return fa[x]=find(fa[x]);
return x;
}
void add(int uu,int vv,int ww){
g[++cnt].u=uu;
g[cnt].v=vv;
g[cnt].w=ww;
}
void kruskal(){
sort(g+1,g+m+1,cmp);
for(int i=1;i<=m;i++){
int u=find(g[i].u);
int v=find(g[i].v);
if(u==v) continue;
ans+=g[i].w;
fa[v]=u;
cnt++;
}
}
int main(){
while(cin>>n){
cnt=0;
if(cacnt!=0) puts("");
cacnt++;
//第一部分
for(int i=1;i<=n-1;i++){
scanf("%d%d%d",&a,&b,&c);
ans+=c;
}
printf("%d\n",ans); ans=0;
//第二部分
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}m+=k;
for(int i=1;i<=m;i++) fa[i]=i;
kruskal();//板子
printf("%d\n",ans);
ans=0;
}
}