即使是基础的算法也能出很难的题啊。
先来一个板子题:
[模板]最小生成树:https://www.luogu.org/problemnew/show/P3366
1 # include <cstdio> 2 # include <iostream> 3 # include <cstring> 4 5 using namespace std; 6 7 int G[5002][5002]={0},M[5002]={0}; 8 bool f[5002]={false}; 9 10 int main() 11 { 12 13 int n,m,x,y,z; 14 memset(G,0x7f,sizeof(G)); 15 scanf("%d%d",&n,&m); 16 for (int i=1;i<=m;i++) 17 { 18 scanf("%d%d%d",&x,&y,&z); 19 if (G[x][y]>=z) 20 G[x][y]=G[y][x]=z; 21 } 22 memset(M,0x7f,sizeof(M)); 23 M[1]=0; 24 memset(f,1,sizeof(f)); 25 for (int i=1;i<=n;i++) 26 { 27 int k=0; 28 for (int j=1;j<=n;j++) 29 if ((f[j]!=0)&&(M[j]<M[k])) k=j; 30 f[k]=false; 31 for (int j=1;j<=n;j++) 32 if (f[j]&&M[j]>G[k][j]) 33 M[j]=G[k][j]; 34 } 35 int A=0,S=0; 36 for (int i=1;i<=n;i++) 37 A+=f[i]; 38 if (A!=0) {printf("orz"); 39 return 0;} 40 for (int i=1;i<=n;i++) 41 S+=M[i]; 42 cout<<S; 43 return 0; 44 }
1 // luogu-judger-enable-o2 2 # include <cstdio> 3 # include <iostream> 4 # include <algorithm> 5 # define R register int 6 7 using namespace std; 8 9 int fx,fy,n,m,ans,S; 10 int F[5009]; 11 struct edge 12 { 13 int x,y,co; 14 }g[200009]; 15 16 bool cmp(edge a,edge b) 17 { 18 return a.co<b.co; 19 } 20 21 int father(int x) 22 { 23 if(x!=F[x]) return F[x]=father(F[x]); 24 return x; 25 } 26 27 int main() 28 { 29 scanf("%d%d",&n,&m); 30 S=n; 31 for (R i=1;i<=m;++i) 32 scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].co); 33 sort(g+1,g+1+m,cmp); 34 for (R i=1;i<=n;++i) 35 F[i]=i; 36 for (R i=1;i<=m;++i) 37 { 38 fx=father(g[i].x); 39 fy=father(g[i].y); 40 if(fx!=fy) 41 F[fx]=fy,S--,ans+=g[i].co; 42 } 43 if(S!=1) 44 printf("orz"); 45 else 46 printf("%d",ans); 47 return 0; 48 }
$Prim$的时间复杂度:$O(V_{2})$;
$Kruskal$时间复杂度:$O(ElogE)$
听说还有一种针对没有重复权值的图的算法:$Boruvka$,对于随机图来说$O(V+E)$,听起来还是很不错的,不过我觉得现在还没必要学这个。