最小生成树-prim算法模板
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz
输入输出格式
输入格式:
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
输入输出样例
说明
时空限制:1000ms,128M
数据规模:
对于20%的数据:N<=5,M<=20
对于40%的数据:N<=50,M<=2500
对于70%的数据:N<=500,M<=10000
对于100%的数据:N<=5000,M<=200000
#include <bits/stdc++.h> #define MAXV 5005 #define INF 0x3fffffff using namespace std; struct Node { int v ,w; Node(int _v ,int _w) : v(_v) ,w(_w) {} }; vector<Node> G[MAXV]; int n ,m ,u ,v ,w; int d[MAXV]; bool vis[MAXV]; int prim(); int main() { scanf("%d%d" ,&n ,&m); for(int i=1 ;i<=m ;i++) { scanf("%d%d%d" ,&u ,&v ,&w); G[u].push_back(Node(v ,w)); G[v].push_back(Node(u ,w)); } int Ans=prim(); if(Ans==-1) printf("orz"); else printf("%d" ,Ans); return 0; } int prim() { fill(d ,d+MAXV ,INF); d[1]=0; int ans=0; for(int i=1 ;i<=n ;i++) { int u=-1 ,minn=INF; for(int j=1 ;j<=n ;j++) if(!vis[j] && d[j]<minn) { u=j; minn=d[j]; } if(u==-1) return -1; vis[u]=true; ans+=d[u]; for(int j=0 ;j<G[u].size() ;j++) { int v=G[u][j].v; if(!vis[v] && G[u][j].w<d[v]) d[v]=G[u][j].w; } } return ans; }