美文网首页
算法模板(五)树基础算法

算法模板(五)树基础算法

作者: 影踪派熊猫人武僧 | 来源:发表于2018-11-08 08:39 被阅读0次

最小生成树

#include<bits/stdc++.h>
#define maxn 5000
#define maxm 10000
using namespace std;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
struct edge{
    int u,int v,int w,int next;
}E[maxm<<1];
bool cmp(edge a,edge b){
    return a.w<b.w;
}
int p[maxn],eid;
inline void init(){
    for(register int i=0;i<maxn;i++)p[i]=-1;
    eid=0;
}
int get(int x){
    if(fa[x]==x)return x;
    return fa[x]=get(fa[x]);
}
inline void insert(int u,int v,int w){
    E[eid].u=u;
    E[eid].v=v;
    E[eid].w=w;
    E[eid].next=p[u];
    p[u]=eid++;
}
inline void insert2(int u,int v,int w){
    insert(u,v,w);
    insert(v,u,w);
}
inline int kru(int n,int m){
    int sum=0;
    for(register int i=0;i<=n;i++)fa[i]=i;
    sort(E,E+m,cmp);
    for(register int i=0;i<m;i++){
        int u=get(E[i].u);
        int v=get(E[i].v);
        if(u!=v){
            fa[v]=u;
            sum+=E[i].w;
        }
    }
}
int main(){
    n=read();m=read();
    for(register int i=0;i<m;i++)E[i].u=read(),E[i].v=read(),E[i].w=read();
    cout<<kru(n,m);
    return 0;
}

求树的直径

#include<bits/stdc++.h>
#define maxn 2000
#define maxm 2000
using namespace std;
struct edge{
    int u,v,w,next;
};
int p[maxn],eid;
inline void init(){
    for(register int i=0;i<maxn;i++)p[i]=-1;
    eid=0;
}
inline void insert(int u,int v,int w){
    E[eid].u=u;
    E[eid].v=v;
    E[eid].w=w;
    E[eid].next=p[u];
    p[u]=eid++;
}
inline void insert2(int u,int v,int w){
    insert(u,v,w);
    insert(v,u,w);
}
int maxlen,point;
void dfs(int u,int pre,int step){
    if(maxlen!=step){
        maxlen=step;
        point=u;
    }
    for(register int i=p[u];~i;i=E[i].next){
        if(E[i].v!=pre){
            dfs(E[i].v,u,step+1);
        }
    }
}
int diamonted(){
    maxlen=-1;
    diameter(1,0,0);
    maxlen=-1;
    diameter(point,0,0);
}
int n,m;
int main(){
    cin>>n>>m;
    int u,v,w;
    for(register int i=0;i<m;i++){
        cin>>u>>v>>w;
        insert2(u,v,w);
    }
    cout<<diameter();
}

求树的重心

#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 100;
const int MAX_M = 10000;
struct edge {
    int v, next;
    int len;
} E[MAX_M];
int p[MAX_N], eid;
void init() {
    memset(p, -1, sizeof(p));
    eid = 0;
}
void insert(int u, int v) {
    E[eid].v = v;
    E[eid].next = p[u];
    p[u] = eid++;
}
int n;
int minNode=-1,minBalance=MAX_N;
int dfs(int u,int pre){
    int sz=0,maxSubtree=0;
    for(int i=p[u];i!=-1;i=E[i].next){
        if(E[i].v!=pre){
            int son=dfs(E[i].v,u);
            sz+=son;
            maxSubtree=max(maxSubtree,son);
        }
    }
    sz++;
    maxSubtree=max(maxSubtree,n-sz);
    if(maxSubtree<minBalance){
        minBalance=maxSubtree;
        minNode=u;
    }
    return sz;
}
int main() {
    cin>>n;
    init();
    for(int i=0;i<n-1;i++){
        int u,v;
        cin>>u>>v;
        insert(u,v);
        insert(v,u);
    }
    dfs(1,0);
    cout<<minNode<<endl;
    return 0;
}

相关文章

网友评论

      本文标题:算法模板(五)树基础算法

      本文链接:https://www.haomeiwen.com/subject/gqybxqtx.html