最小生成树
prim 算法模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<math.h> #include<queue> #include<stack> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long long ll; typedef pair<int,int> PII; #define mod 1000000007 #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second //head #define INF 0x3f3f3f3f #define maxn 109 int g[maxn][maxn]; int dis[maxn]; bool used[maxn]; int n; int prim(int st) { int cost=0; for(int i=1;i<=n;i++) { used[i]=false; dis[i]=g[st][i]; } used[st]=true; for(int i=1;i<=n;i++) { int minn=INF; int v=-1; for(int j=1;j<=n;j++) { if(!used[j]&&minn>dis[j]) { minn=dis[j]; v=j; } } if(v==-1) break; cost+=dis[v]; used[v]=true; for(int j=1;j<=n;j++) { if(!used[j]&&dis[j]>g[v][j]) { dis[j]=g[v][j]; } } } return cost; } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&g[i][j]); printf("%d\n",prim(1)); } return 0; }
kruskal 算法模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<math.h> #include<queue> #include<stack> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long long ll; typedef pair<int,int> PII; #define mod 1000000007 #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second //head #define maxn 105 int par[maxn],cnt; int n; struct EDGE { int from,to,w; bool operator < (const EDGE &rhs) const{ return this->w<rhs.w; } }edge[maxn*maxn]; void Addedge(int from,int to,int cost) { edge[cnt].from=from; edge[cnt].to=to; edge[cnt].w=cost; cnt++; } void init() { for(int i=1;i<=n;i++) par[i]=i; cnt=0; } int Findset(int x) { if(x==par[x]) return x; else return par[x]=Findset(par[x]); } int kruskal() { sort(edge,edge+cnt); int edgecnt=0; int cost=0; for(int i=0;i<cnt;i++) { int x=Findset(edge[i].from); int y=Findset(edge[i].to); if(x!=y) { par[x]=y; cost+=edge[i].w; edgecnt++; } if(edgecnt==n-1) break; } return edgecnt==n-1?cost:-1; } int main() { while(~scanf("%d",&n)) { init(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int w; scanf("%d",&w); Addedge(i,j,w); } printf("%d\n",kruskal()); } return 0; }