常用模板1

1.最小生成树

这里给出克鲁斯卡尔的板子。

#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,fa[5001];
struct edge{
	int x,y,z;
	bool operator <(const edge &t) const{return t.z>z;}
}a[200001];
int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)fa[i]=i;
	for (int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+m+1);
	int sum=0;
	for (int i=1;i<=m;i++)
	{
		int fx=getfa(a[i].x),fy=getfa(a[i].y);
		if (fx!=fy)
		{
			sum+=a[i].z;
			fa[fx]=fy;
		}
	}
	printf("%d",sum);
	return 0;
}

2.并查集(压缩路径)

#include<cstdio>
using namespace std;
int n,m,fa[10001];
int getfa(int x)
{
	if (x==fa[x]) return x;
	fa[x]=getfa(fa[x]);return fa[x];
}
int main()
{
	scanf("%d%d",&n,&m);
	int x,y,z;
	for (int i=1;i<=n;i++)fa[i]=i;
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&z,&x,&y);
		int fx=getfa(x),fy=getfa(y);
		if (z==1&&fx!=fy)
		{
			fa[fx]=fy;
		}
		else if (z==2)
		{
			if (fx==fy) printf("Y\n");else printf("N\n");
		}
	}
	return 0;
}


3.单源最短路

spfa

#include<cstdio>
#include<cstring>
using namespace std;
struct edge{int to,next,value;}a[500001];
int n,m,s,h[10001],line[100001],vis[10001];
bool bo[10001];
int main()
{
	scanf("%d%d%d",&n,&m,&s);
	int x,y,z,cnt=0;
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		a[++cnt].value=z;a[cnt].to=y;a[cnt].next=h[x];h[x]=cnt;
	}
	int l=0,r=1;line[1]=s;
	memset(bo,true,sizeof(bo));
	memset(vis,0x3f,sizeof(vis));vis[s]=0;bo[s]=false;
	while (++l<=r)
	{
		x=line[l];bo[x]=true;
		for (int i=h[x];i;i=a[i].next)
		{
			if (vis[x]+a[i].value<vis[a[i].to])
			{
				vis[a[i].to]=vis[x]+a[i].value;
				if (bo[a[i].to]) {line[++r]=a[i].to;bo[a[i].to]=false;}
			}
		}
	}
	for (int i=1;i<=n;i++)if (vis[i]>1e8) printf("2147483647 ");else printf("%d ",vis[i]);
	return 0;
}

4.线性筛(欧拉筛)

#include<cstdio>
#include<cstring>
using namespace std;
int prime[5000001],n,m,cnt;
bool bo[10000001];
void find()
{
	for(int i=2;i<=n;i++)
	{
		if (bo[i])prime[++cnt]=i;
		for (int j=1;j<=cnt&&prime[j]*i<=n;j++)
		{
			bo[i*prime[j]]=false;
			if (i%prime[j]==0)break;
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(bo,true,sizeof(bo));
	bo[1]=false;
	find();int x;
	for (int i=1;i<=m;i++)	
	{
		scanf("%d",&x);
		if (bo[x]) printf("Yes\n");else printf("No\n");
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值