可谓很基础的模板题,问题就是用prim堆优化做一直无法ac,但是kruscal(并查集写法)很好写
networking 之 kruscal:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
int pre[105];
struct node
{
int u;
int v;
int w;
}a[10010];
bool cmp(node a, node b)
{
return a.w < b.w;
}
int find(int a)
{
if(pre[a] == -1)return a;
else return find(pre[a]);
}
int join(int a, int b)
{
int i = find(a);
int j = find(b);
if(i != j)
{
pre[i] = j;
return 1;
}
return 0;
}
int main()
{
int m, n;
int ans;
while(scanf("%d",&n)!=EOF && n)
{
scanf("%d",&m);
ans = 0;
for(int i = 0; i < n; i ++)pre[i] = -1;
for(int i = 0; i < m; i ++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a,a+m,cmp);
for(int i = 0; i < m; i ++)
{
if(join(a[i].u,a[i].v))
ans += a[i].w;
}
printf("%d\n",ans);
}
return 0;
}
先按权值排序,如果不在并查集集合内,就加上这条边的权值,可以说就是一道并查集问题了
用这代码稍微一改轻松ac鹏哥留的畅通工程,感觉是一类题,就放在一起了:
畅通工程 之 kruscal:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
int pre[105];
struct node
{
int u;
int v;
int w;
}a[10010];
bool cmp(node a, node b)
{
return a.w < b.w;
}
int find(int a)
{
if(pre[a] == -1)return a;
else return find(pre[a]);
}
int join(int a, int b)
{
int i = find(a);
int j = find(b);
if(i != j)
{
pre[i] = j;
return 1;
}
return 0;
}
int main()
{
int m, n;
int ans;
int tot;
char c = '?';
while(scanf("%d",&m)!=EOF && m)
{
scanf("%d",&n);
ans = 0;
tot = 1;
for(int i = 0; i < n; i ++)pre[i] = -1;
for(int i = 0; i < m; i ++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a,a+m,cmp);
for(int i = 0; i < m; i ++)
{
if(join(a[i].u,a[i].v)){
ans += a[i].w;
tot++;
}
}
if(tot >= n)
printf("%d\n",ans);
else if(tot < n) printf("%c\n",c);
}
return 0;
}