常用模板汇总

SPFA单源最短路

struct nod{
	int to,w;
};
vector <nod> g[100005];
bool vis[500005];
int dis[100005];

int n,m,s;

void spfa()
{
	dis[s]=0;
	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		int now=q.front();q.pop();
		vis[now]=0;
		for(int i=0;i<g[now].size();i++)
		{
			nod nex=g[now][i];
			if(dis[now]+nex.w<dis[nex.to])
			{
				dis[nex.to]=dis[now]+nex.w;
				if(!vis[nex.to])
				{
					vis[nex.to]=1;
					q.push(nex.to);
				}
			}
		}
	}
}

int main(int argc, char const *argv[])
{
	read(n),read(m),read(s);
	for(int i=1;i<=m;i++)
	{
		int x,y,w;
		read(x),read(y),read(w);
		nod tmp;
		tmp.to=y;tmp.w=w;
		g[x].push_back(tmp);
	}
	for(int i=1;i<=n;i++)
		vis[i]=0,dis[i]=2147483647;
	spfa();
	for(int i=1;i<=n;i++)
	{
		if(s==i)
			printf("0 ");
		else
			printf("%d ",dis[i]);
	}
	return 0;
}

Tarjan求LCA

#include<bits/stdc++.h>
#define MAXN 500005
using namespace std;
typedef long long LL;
int fa[MAXN],xx[MAXN],yy[MAXN];
int n,m,q;
map <int,int> ans[MAXN];
vector<int> edge[MAXN],cha[MAXN];
bool vis[MAXN];

inline void read(int &x){
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	x*=f;
}

void init()
{
	for(int i=1;i<=n;i++)
		fa[i]=i;
}

int getfa(int x)
{
	return fa[x]==x?x:fa[x]=getfa(fa[x]);
}

void unio(int x,int y)
{
	int xx=getfa(x),yy=getfa(y);
	if(xx!=yy)
		fa[yy]=xx;
}
void tarjan(int x,int la)
{
	int lens=edge[x].size();
	for(int i=0;i<lens;i++)
	{
		if(edge[x][i]!=la)
		{
			tarjan(edge[x][i],x);
			unio(x,edge[x][i]);
			vis[edge[x][i]]=1; 
		}
	}
	lens=cha[x].size();
	for(int i=0;i<lens;i++)
		if(vis[cha[x][i]])
		{
			ans[x][cha[x][i]]=getfa(cha[x][i]);
			ans[cha[x][i]][x]=getfa(cha[x][i]);
		}
}
int main()
{
	read(n),read(m),read(q);
	init();
	for(int i=1;i<n;i++)
	{
		int u,v;
		read(u),read(v);
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	for(int i=1;i<=m;i++)
	{
		read(xx[i]),read(yy[i]);
		cha[xx[i]].push_back(yy[i]);
		cha[yy[i]].push_back(xx[i]);
	}
	tarjan(q,0);
	for(int i=1;i<=m;i++)
		printf("%d\n",ans[xx[i]][yy[i]]);
	return 0;
}

最小生成树kruskal

struct nod{
	int x,y,w;
}e[400005];
int fa[400005];
int n,m;

bool cmp(nod a,nod b)
{
	return a.w<b.w;
}

int find(int x)
{
	if(fa[x]==x)
		return x;
	return fa[x]=find(fa[x]);
}

int main(int argc, char const *argv[])
{
	read(n),read(m);
	int ans=0;
	for(int i=1;i<=m;i++)
		read(e[i].x),read(e[i].y),read(e[i].w);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	stable_sort(e+1,e+m+1,cmp);
	for(int i=1;i<=m;i++)
	{
		int u=find(e[i].x),v=find(e[i].y);
		if(u==v) continue;
		ans+=e[i].w;
		fa[u]=v;
	}
	if(!ans)
		printf("orz\n");
	else
		printf("%d\n",ans);
	return 0;
}

priority_queue <int,vector<int>,less<int>> q1;
priority_queue <int,vector<int>,greater<int>> q2;

斐波那契数列递推

ll a[3][3];
ll res[3][3],ans[3][3];

void mul(ll x[3][3],ll y[3][3])
{
	memset(res,0,sizeof(res));
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
			for(int k=1;k<=2;k++)
				res[i][j]=(res[i][j]+x[i][k]*y[k][j])%mod;
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
			x[i][j]=res[i][j];
}

int main()
{
    n-=2;
    a[1][1]=1,a[1][2]=1,a[2][1]=1,a[2][2]=0;
    ans[1][1]=1,ans[1][2]=1;
    while(n)
    {
    	if(n&1)
            mul(ans,a);
	n>>=1;
	mul(a,a);
    }
    printf("%lld\n",ans[1][1]);
}

矩阵快速幂

struct nod{
	long long a[105][105];
};

nod a,b,c;

inline void out(nod c)
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			cout<<c.a[i][j]<<" ";
		cout<<endl;
	}
}

inline nod mul(nod a,nod b)
{
	nod ans;
	memset(ans.a,0,sizeof(ans.a));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)
			{
				ans.a[i][j]=(ans.a[i][j]+(a.a[i][k]*b.a[k][j]))%mod;
			}
	return ans;
}

inline nod kuaisumi(nod a,int k)
{
	nod ans;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			if(i==j) ans.a[i][j]=1;
			else ans.a[i][j]=0;
		}
	while(k)
	{
		if(k&1)
			ans=mul(ans,a);
		a=mul(a,a);
		k>>=1;
	}
	return ans;
}

组合数

void work()
{
	for(int i=0;i<=n;i++)
		c[i][i]=c[i][0]=1;
	for(int i=2;i<=n;i++)
		for(int j=1;j<=i;j++)
			c[i][j]=c[i-1][j-1]+c[i-1][j];
}

文件输入输出

    #ifndef file
	char IN[105]=".in";
	char OUT[105]=".out";
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
    #endif

    #ifndef file
	fclose(stdin);
	fclose(stdout);
    #endif

二分排序

int A(int l,int r)
{
	int mid=a[(l+r)/2];
	int i=l,j=r;
	while(i<=j)
	{
		while(a[i]<mid&&i<=r)
		    i++;
		while(a[j]>mid&&j>=l)
		    j--;
		if(i<=j)
		{
			swap(a[i],a[j]);
			i++;
			j--;
		}
	}
		if(l<=j)
		    A(l,j);
		if(i<=r)
		    A(i,r);
	return 0;
}

欧拉筛

bool isprime[10005];
int prime[5005];
int top=1;

memset(isprime,1,sizeof(isprime));
for(int i=2;i<10000;i++)
{
	if(isprime[i])
		prime[top++]=i;
	for(int j=1;j<top;j++)
	{
		if(i*prime[j]>10000)
			break;
		isprime[i*prime[j]]=0;
		if(i%prime[j]==0)
			break;
	}
}

高精加

string s,sx;
int a[505],b[505],ans[505];

int main(int argc, char const *argv[])
{
	cin>>s>>sx;
	memset(a,sizeof(a),0);
	memset(b,sizeof(b),0);
	for(int i=0,pos=s.size();i<s.size();i++,pos--)
		a[pos]=s[i]-'0';
	for(int i=0,pos=sx.size();i<sx.size();i++,pos--)
		b[pos]=sx[i]-'0';
	int jinwei=0,len=max(s.size(),sx.size());
	for(int i=1;i<=len;i++)
	{
		ans[i]=(a[i]+b[i]+jinwei)%10;
		jinwei=(a[i]+b[i]+jinwei)/10;
	}
	if(jinwei)
	{
		cout<<jinwei;
		for(int i=len;i;i--)
			cout<<ans[i];
	}
	else
		for(int i=len;i;i--)
			cout<<ans[i];
	return 0;
}

快速读入

整数

inline void read(int &x){
	x=0;int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	x*=f;
}

实数(注意输入必须要包含小数点)

inline void read(double &x){
	x=0;int f=1;double y=1.0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x*10)+(ch^48);
		ch=getchar();
	}
	ch=getchar();
	while(ch>='0'&& ch<='9'){
		x+=(y/=10)*(ch^48);
		ch=getchar();
	}
	x*=f;
}
posted @ 2019-10-13 18:09  WJSoj  阅读(167)  评论(0编辑  收藏  举报