You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
www/min_tree_teacher.cpp

68 lines
1.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include<stdio.h>
#include <algorithm>
/*
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
*/
#define INT 0x3f3f3f3f
using namespace std;
const int maxn = 5010;
int a[maxn][maxn];//起始点和终点的数组
int vis[maxn],dist[maxn];//vis[]表示是否已经被访问dist表示到当前节点的最小权值
int n,m;//节点数和边数
int u,v,w;//u到v的权值
long long sum = 0;//最小生成树的权值
int prim(int pos)
{
dist[pos] = 0;//初始值设置为0
for(int i = 1 ; i<=n ; i++)//遍历节点,使其默认为未访问
{
int cur = -1;//vis[-1]表示未被访问
for(int j = 1; j <=n ; j++)
{
/*这个if用来判断当前是否是为距离已访问节点最近节点的权值为最小值
cur = -1代表着未访问那么肯定要访问通过for循环来进行访问
fori是将每个节点进行循环forj是通过对cur和dist数值进行比值
dist除10其他的初始化为INT
*/
if(!vis[j] && (cur == -1 || dist[j] < dist[cur]))
cur = j;//更新访问状态
}//第一次出门的时候cur = 1j>n
if (dist[cur] >= INT) return INT;
sum += dist[cur];
vis[cur] = 1;
for(int k = 1; k <= n; k++)
/*第一次for已经选择了j节点作为起点
开始计算dist[]后续的fork其实是更新min*/
{
if(!vis[k])
dist[k] = min(dist[k],a[cur][k]);
}
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
memset(a,0x3f,sizeof(a));
memset(dist,0x3f,sizeof(dist));
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
a[u][v] = min(a[u][v],w);
a[v][u] = min(a[v][u],w);
}
int value = prim(1);
if(value >= INT) puts("orz");
else printf("%lld\n",sum);
return 0;
}