码迷,mamicode.com
首页 > 编程语言 > 详细

考前算法总结

时间:2020-11-04 18:47:58      阅读:18      评论:0      收藏:0      [点我收藏+]

标签:printf   ems   lowbit   next   +=   c++   priority   初始   jks   

最短路

SPFA

#include <bits/stdc++.h>
using namespace std;
#define N 10001
#define M 500001 
struct node{
	int to,w,next;
}edge[M];
int cut=0;
int head[N];
int dis[N];
int n,m,k;
bool vis[N];
queue<int> q;
void ini(){
	fill(dis+1,dis+N+1,INT_MAX);
	memset(head,-1,sizeof(head));
}
void add(int u,int v,int w){//建边 
	cut++;
	edge[cut].w=w;
	edge[cut].to=v;
	edge[cut].next=head[u];
	head[u]=cut;
}
void SPFA(int x){
	dis[x]=0;
	q.push(x);//头入队 
	vis[x]=1;
	while(!q.empty()){
		int u=q.front();q.pop();vis[u]=false;
		for(int j=head[u];~j;j=edge[j].next){//调用邻接表 
			if(dis[edge[j].to]>dis[u]+edge[j].w){
				dis[edge[j].to]=dis[u]+edge[j].w;//松弛操作 
				if(!vis[edge[j].to]){//判断标记 
					q.push(edge[j].to);//入队边上的点 
					vis[edge[j].to]=1;//标记 
				}
			}
		}
	}
} 
int main(){
	
	ini();
	scanf("%d %d %d",&n,&m,&k);
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d %d %d",&u,&v,&w);
		add(u,v,w);
	}
	SPFA(k);
	for(int i=1;i<=n;i++){
		printf("%d ",dis[i]);
	}
		
    return 0;
}

Dijkstra(堆优化)

#include <bits/stdc++.h>
using namespace std;
#define N 10001
#define M 500001 
#define P pair<int,int>  
#define Fi first
#define Se second
struct node{
	int to,w,next;
}edge[M];
int cut=0;
int head[N];
int dis[N];
int n,m,k;
bool vis[N];
priority_queue<P,vector<P>,greater<P> > q;//优先队列 
void ini(){
	fill(dis+1,dis+N+1,INT_MAX);
	memset(head,-1,sizeof(head));
}
void add(int u,int v,int w){
	cut++;
	edge[cut].w=w;
	edge[cut].to=v;
	edge[cut].next=head[u];
	head[u]=cut;
}
void Dij(int x){
	dis[x]=0;
	vis[x]=1;
	q.push(P(0,x));//头入队 
	while(!q.empty()){
		P u=q.top();q.pop();vis[u.Se]=1;
		for(int j=head[u.Se];~j;j=edge[j].next){//邻接表遍历 
			if(!vis[edge[j].to]&&dis[edge[j].to]>dis[u.Se]+edge[j].w){//判断标记和松弛操作 
				dis[edge[j].to]=dis[u.Se]+edge[j].w;//松弛 
				q.push(P(dis[edge[j].to],edge[j].to));//入队 
			}
		}
	}
} 
int main(){
	
	ini();
	scanf("%d %d %d",&n,&m,&k);
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d %d %d",&u,&v,&w);
		add(u,v,w);
	}
	Dij(k); 
	for(int i=1;i<=n;i++){
		printf("%d ",dis[i]);
	}
		
    return 0;
}

最小生成树

Kruskal

#include <bits/stdc++.h>
using namespace std;
#define N 5001
#define M 200001
struct node{
	int u,v,w;
}edge[M];
int fa[N],n,m;
int find(int x){//并查集找爸爸 
	return fa[x]==x?x:fa[x]=find(fa[x]);
} 
void un(int x,int y){//并查集连接 
	x=find(x);
	y=find(y);
	fa[x]=y;
}
void ini(){//初始化 
	for(int i=1;i<=5000;i++)fa[i]=i;
}
bool cmp(node a,node b){
	return a.w<b.w;
}
int main(){
	
	ini();
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);
	}
	sort(edge+1,edge+m+1,cmp);
	int k=0;
	int ans=0;
	for(int i=1;i<=m;i++){
		if(find(edge[i].u)!=find(edge[i].v)){//判断是否在一个集合里 
			un(edge[i].u,edge[i].v);
			k++;
			ans+=edge[i].w;//累加答案 
		}
		if(k==n-1)break;
	}
	if(k==n-1)printf("%d",ans);
	else printf("orz");//不连通 
		
    return 0;
}

排序

归并排序(求逆序对)

#include<bits/stdc++.h>
using namespace std;
int n;
int ans=0;
int v[500001];
int t[500001];
void Qsort(int l,int r){//归并 
	if(l==r)return ;
	int mid=(l+r)>>1;
	Qsort(1,mid);
	Qsort(mid+1,r);//递归 
	int i=l;int j=mid+1;int k=l;
	while(i<=mid&&j<=r){
		if(v[i]<=v[j])t[k++]=v[i++];
		else t[k++]=v[j++],ans+=mid-i+1;//数学规律 
	}
	while(i<=mid)t[k++]=v[i++];
	while(j<=r)t[k++]=v[j++];
	for(int i=l;i<=r;i++)v[i]=t[i];
}
int main(){
	
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&v[i]);
	Qsort(1,n);
	printf("%d",ans);
	
	return 0;
}

数据结构

树状数组(区间查询,区间修改)

#include<bits/stdc++.h>
using namespace std;
int a[500001],b[500001],c[500001];
int n,m;
int lowbit(int x){
	return x&(-x);
}
void updata(int i,int k){
	int x=i;
	while(i<=n){
		c[i]+=k;
		b[i]+=k*(x-1);
		i+=lowbit(i);
	}
}
int getsum(int i){
	int sum=0,x=i;
	while(i>0){
		sum+=x*c[i]-b[i];
		i-=lowbit(i);
	}
	return sum;
}
//1:区间修改,2:区间查询 
int main(){
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		updata(i,a[i]-a[i-1]);
	}
	for(int i=1,d,x,y,z;i<=m;i++){
		scanf("%d",&d);
		if(d==1){
			scanf("%d%d%d",&x,&y,&z);
			updata(x,z);
			updata(y+1,-z);
		}else{
			scanf("%d%d",&x,&y);
			printf("%d\n",getsum(y)-getsum(x-1));
		}
	}
	
	return 0;
}

考前算法总结

标签:printf   ems   lowbit   next   +=   c++   priority   初始   jks   

原文地址:https://www.cnblogs.com/binghun/p/13924146.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!