[template] minimum spanning tree [minimum spanning tree] [prim kruskal]

Keywords: PHP less

prim:

  1. First, build a tree with only one node, which can be any node in the original graph
  2. Using an edge to expand the tree requires that one vertex of the edge is in the tree and the other vertex is not in the tree, and the weight of the edge is the minimum.
  3. Repeat step 2 until all vertices are in the tree

Look at the teacher's template again. By the way, the priority queue of perceptual understanding is renewed

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
#define ll long long
#define rg register
const int N=1000+5,M=1000000+5,inf=0x3f3f3f3f,P=19650827;
int n,m;
ll ans=0;
typedef pair<int,int>pii;                        //pair
priority_queue<pii,vector<pii>,greater<pii> >q; //Small top pile 
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

int tot=0,head[N];
struct edge{int v,nxt,w;}e[M<<1];
void add(int u,int v,int w){
    e[++tot]=(edge){v,head[u],w};head[u]=tot;
}

int dis[N],vis[N];
void prim(){
    memset(vis,0,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    q.push(make_pair(dis[1]=0,1));
    while(!q.empty()){
        int u=q.top().second;q.pop();
        if(vis[u]) continue;
        ans+=dis[u],vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].v,w=e[i].w;
            if(!vis[v]&&dis[v]>w){
                dis[v]=w;
                q.push(make_pair(dis[v],v));
            }
        }
    }
}
int main(){
    rd(n),rd(m);
    int u,v,w;
    for(rg int i=1;i<=m;++i){
        rd(u),rd(v),rd(w);
        add(u,v,w),add(v,u,w);
    }
    prim();
    printf("%lld",ans);
    return 0;
}
 

P3366 [template] minimum spanning tree Add a cnt to record how many points are added, and if the number is less than n, it means no connection

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<stack>
 7 #include<algorithm>
 8 using namespace std;
 9 #define ll long long
10 #define rg register
11 const int N=5000+5,M=200000+5,inf=0x3f3f3f3f,P=19650827;
12 int n,m;
13 ll ans=0;
14 typedef pair<int,int>pii;                        //pair
15 priority_queue<pii,vector<pii>,greater<pii> >q; //Small top pile 
16 template <class t>void rd(t &x){
17     x=0;int w=0;char ch=0;
18     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
19     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
20     x=w?-x:x;
21 }
22 
23 int tot=0,head[N];
24 struct edge{int v,nxt,w;}e[M<<1];
25 void add(int u,int v,int w){
26     e[++tot]=(edge){v,head[u],w};head[u]=tot;
27 }
28 
29 int dis[N],vis[N],cnt=0;
30 bool prim(){
31     memset(vis,0,sizeof(vis));
32     memset(dis,inf,sizeof(dis));
33     q.push(make_pair(dis[1]=0,1));
34     while(!q.empty()){
35         int u=q.top().second;q.pop();
36         if(vis[u]) continue;
37         ans+=dis[u],vis[u]=1,++cnt;
38         for(int i=head[u];i;i=e[i].nxt){
39             int v=e[i].v,w=e[i].w;
40             if(!vis[v]&&dis[v]>w){
41                 dis[v]=w;
42                 q.push(make_pair(dis[v],v));
43             }
44         }
45     }
46     if(cnt!=n) return 0;
47     else return 1;
48 }
49 int main(){
50     rd(n),rd(m);
51     int u,v,w;
52     for(rg int i=1;i<=m;++i){
53         rd(u),rd(v),rd(w);
54         add(u,v,w),add(v,u,w);
55     }
56     if(!prim()) printf("orz");
57     else printf("%lld",ans);
58     return 0;
59 }
60  
3366 prim

 

kruskal

  1. The edges are sorted according to the edge weight from small to large, and a graph T without edges is established
  2. Select an edge with the least weight that has not been selected.
  3. If the two vertices of this edge are in different connected blocks in T, then add it to the graph t
  4. Repeat 2 and 3 until graph T is connected.

Because only the connectivity needs to be maintained, it is not necessary to actually establish graph T, and it can be maintained by concurrent query sets

I just don't know why there will be stack overflow in sorting within the structure. I can only write a cmp to sort the code run of the senior and stack overflow QAQ

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<stack>
#include<algorithm>
using namespace std;
#define ll long long
#define rg register
const int N=1000+5,M=1000000+5,inf=0x3f3f3f3f,P=19650827;
int n,m,cnt=0,f[N];
ll ans=0;

template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct edge{
    int u,v,w;
    bool operator<(const edge&A){return w<A.w;}
}e[M];
bool cmp(const edge &a,const edge &b) {return a.w<b.w;}
int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}

void kruskal(){
    for(rg int i=1;i<=n;++i) f[i]=i;
    for(rg int i=1,u,v;i<=m;++i){
        u=e[i].u,v=e[i].v;
        if(find(u)!=find(v)){
            f[f[u]]=f[v];
            ans+=e[i].w;
        }
    }
}

int main(){
    rd(n),rd(m);
    for(int i=1,u,v,w;i<=m;++i){
        rd(u),rd(v),rd(w);
        e[i]=(edge){u,v,w};
    }
    sort(e+1,e+1+m,cmp);
    kruskal();
    printf("%lld",ans);
    return 0;
}
 

Posted by hardyvoje on Mon, 04 Nov 2019 13:38:10 -0800