最小生成树
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
在一个无向图中,求最小生成树。
Input
多组测试数据,对于每组测试数据,第1行输入正整数n(1 <= n <= 1000)、m,表示n个顶点(编号从1开始)和m条边。之后m行每行输入u(1 <= u <= n)、v(1 <= v <= n)、w(1 <= w <= 100),表示在顶点u和顶点v之间存在无向边,且权值为w。
Output
对于每组测试数据,若存在最小生成树则输出最小生成树的权值和,若不存在最小生成树则输出-1。
Sample Input
3 7 1 2 19 2 3 11 3 1 7 1 3 5 2 3 89 3 1 91 1 2 32
Sample Output
16
Hint
Source
xry-fhf
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int u, v, w;
} Sj;
Sj f[1000000];
int q[10001];
int cmp(const void *a, const void *b) {
Sj *aa = (Sj *)a;
Sj *bb = (Sj *)b;
return aa->w > bb->w ? 1 : -1;
}
int cz(int i) {
int c = i;
for (; q[c] >= 0; c = q[c])
;
while (c != i) {
int t = q[i];
q[i] = c;
i = t;
}
return c;
}
void jh(int a, int b) {
int f1 = cz(a);
int f2 = cz(b);
int t = q[f1] + q[f2];
if (q[f1] > q[f2]) {
q[f1] = f2;
q[f2] = t;
} else {
q[f2] = f1;
q[f1] = t;
}
}
int main() {
int n, m;
while (cin >> n >> m) {
for (int i = 0; i < m; i++) cin >> f[i].u >> f[i].v >> f[i].w;
qsort(f, m, sizeof(f[0]), cmp);
memset(q, -1, sizeof(q));
int ans = 0;
int c = 0;
for (int i = 0; i < m; i++) {
int u = f[i].u;
int v = f[i].v;
if (cz(u) != cz(v)) {
c++;
ans += f[i].w;
jh(u, v);
}
}
if (c == n - 1)
cout << ans << endl;
else
cout << "-1" << endl;
}
}
或者
#include <bits/stdc++.h>
using namespace std;
int f[1200];
struct node
{
int u,v,w;
}e[120000];
int cmp(struct node a,struct node b)
{
return a.w<b.w;
}//按路径权值排序
int getf(int a)
{
if(f[a]==a)
{
return a;
}
f[a]=getf(f[a]);
return f[a];
}//并查集查找父节点
int bingchaji(int a,int b)
{
int t1,t2;
t1=getf(a);
t2=getf(b);
if(t1!=t2)//判断两点是否在同一个集合中
{
f[t2]=t1;
return 1;//表明未连接
}
return 0;
}//并查集合并
int main()
{
int n,m,i,sum,num;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
}
sort(e+1,e+m+1,cmp);//从小到大排序
for(i=1;i<=n;i++)
{
f[i]=i;
}//并查集初始化
num=0;sum=0;
//kruskal核心代码
for(i=1;i<=m;i++)
{
if(bingchaji(e[i].u,e[i].v))//判断是否已经在一个集合中
{
num++;
sum+=e[i].w;
}
if(num==n-1)
break;
}
if(num!=n-1)//当不存在最小生成树的时候
{
printf("%d\n",-1);
}
else
{
printf("%d\n",sum);
}
}
return 0;
}