最小生成树问题模板

prime算法

#include
using namespace std;
int n,m,head[5005],cnt,res,dis[5005],num;
struct Node
{
	int u,v,w,next;
}edge[400005]; 
void add(int u,int v,int w){
	edge[++cnt].next=head[u];
	head[u]=cnt;
	edge[cnt].u=u;
	edge[cnt].v=v;
	edge[cnt].w=w;
}
void prim()
{
	dis[1]=0,num=1;
	for(int i=head[1];i!=-1;i=edge[i].next) dis[ edge[i].v ]=min(dis[edge[i].v],edge[i].w);
	while(num<n)
	{
		int minn=0x3f3f3f3f,mini=-1;
		for(int i=1;i<=n;i++)
		{
			if(dis[i]&&dis[i]<minn)
			{
				minn=dis[i],mini=i;
			}
		}
		if(minn==0x3f3f3f3f) return ;
		dis[mini]=0,num++,res+=minn;
		for(int i=head[mini];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v,u=edge[i].u,w=edge[i].w;
			dis[v]=min(dis[v],w);
		}
	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	memset(head,-1,sizeof(head));
	memset(dis,0x3f3f3f3f,sizeof(dis));
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
		add(v,u,w);
	}
	prim();
	if(num==n) cout<<res;
	else cout<<"orz";
	return 0;
} 

堆优化prim

#include
#include
#include
#include
#include
using namespace std;

int k,n,m,cnt,sum,ai,bi,ci,head[5005],dis[5005],vis[5005];

struct Edge
{
    int v,w,next;
}e[400005];

void add(int u,int v,int w)
{
    e[++k].v=v;
    e[k].w=w;
    e[k].next=head[u];
    head[u]=k;
}

typedef pair <int,int> pii;
priority_queue <pii,vector<pii>,greater<pii> > q;

void prim()
{
    dis[1]=0;
    q.push(make_pair(0,1));
    while(!q.empty()&&cnt<n)
    {
        int d=q.top().first,u=q.top().second;
        q.pop();
        if(vis[u]) continue;
        cnt++;
        sum+=d;
        vis[u]=1;
        for(int i=head[u];i!=-1;i=e[i].next)
            if(e[i].w<dis[e[i].v])
                dis[e[i].v]=e[i].w,q.push(make_pair(dis[e[i].v],e[i].v));
    }
}

int main()
{
    memset(dis,127,sizeof(dis));
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&ai,&bi,&ci);
        add(ai,bi,ci);
        add(bi,ai,ci);
    }
    prim();
    if (cnt==n)printf("%d",sum);
    else printf("orz");
}

kruskal算法

#include
using namespace std;
int n,m,num,f[5005];
struct Node
{
	int u,v;
	long long w;
	bool operator <(const Node b) const
	{
		return w<b.w;
	}
}edge[200005];
long long res;
int find(int x)
{
	if(f[x]==x) return x;
	else{
		f[x]=find(f[x]);
		return f[x];
	}
	
}
void KRU()
{
	int uu,vv,ww;
	for(int i=0;i<m;i++)
	{
		uu=find( edge[i].u ),vv=find( edge[i].v ),ww=edge[i].w;
		if(uu==vv) continue;
		f[uu]=vv;
		res+=ww;
		num++;
		if(num==n-1) break;
	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=0;i<m;i++) cin>>edge[i].u>>edge[i].v>>edge[i].w;
	sort(edge,edge+m);
	KRU();
	if(num==n-1)
	cout<<res<<endl;
	else cout<<"orz"<<endl;
	return 0;
}

你可能感兴趣的:(笔记)