最小生成树——Prim算法和Kruskal算法(暂未更新完毕)

Prim算法

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<time.h>
#include<queue>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define sc second
ld eps=1e-9;
ll pp=1000000007;
ll inf=2147483647;
#define maxn 5005
#define maxm 200005
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll read(){
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
//head 


struct edge
{
    int to,_dis,next;
}edge[maxm<<1];

int head[maxn],dis[maxn],cnt,n,m,tot,now=1,ans;
bool vis[maxn];

inline void add_edge(int from,int to,int value)
{
    edge[++cnt].to=to;
    edge[cnt]._dis=value;
    edge[cnt].next=head[from];
    head[from]=cnt;
}

inline int prim()
{
    rep(i,2,n)
        dis[i]=inf;
    for(int i=head[1];i;i=edge[i].next)
        dis[edge[i].to]=min(dis[edge[i].to],edge[i]._dis);
    while(++tot<n)
    {
        int minn=inf;
        vis[now]=1;
        rep(i,1,n)
            if(!vis[i]&&minn>dis[i])
                minn=dis[i],now=i;
        ans+=minn;
        for(int i=head[now];i;i=edge[i].next)
        {
            int to=edge[i].to;
            if(dis[to]>edge[i]._dis&&!vis[to])
                dis[to]=edge[i]._dis;
        }
        
    }
    return ans;
}
int main()
{
    n=read(),m=read();
    rep(i,1,m)
    {
        int from=read(),to=read(),value=read();
        add_edge(from,to,value);
        add_edge(to,from,value);
    }
    cout<<prim();
}

 克鲁斯卡尔

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<time.h>
#include<queue>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define sc second
ld eps=1e-9;
ll pp=1000000007;
ll inf=2147483647;
#define maxn 5005
#define maxm 200005
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll read(){
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
//head 

struct Edge
{
    int from,to,_dis;
}edge[maxm];
int fa[maxn],n,m,ans,eu,ev,cnt;
bool cmp(Edge a,Edge b)
{
    return a._dis<b._dis;
}
inline int find_die(int x)
{
    while(x!=fa[x]) x=fa[x]=fa[fa[x]];
    return x;
} 
inline int kruskal()
{
    sort(edge+1,edge+1+m,cmp);
    rep(i,1,m)
    {
        eu=find_die(edge[i].from);
        ev=find_die(edge[i].to);
        if(eu==ev)
            continue;
        ans+=edge[i]._dis;
        fa[ev]=eu;
        if(++cnt==n-1)
            break;
    }
    return ans;
}

int main()
{
    n=read(),m=read();
    rep(i,1,n)
        fa[i]=i;
    rep(i,1,m)
    {
        edge[i].from=read(),edge[i].to=read(),edge[i]._dis=read();
        
    }
    cout<<kruskal();
}

猜你喜欢

转载自www.cnblogs.com/lcezych/p/10752573.html