其他分享
首页 > 其他分享> > 链式前向星板子】

链式前向星板子】

作者:互联网

一种存边的结构

结构

包括 head nxt to 三个数组 和一个变量 cnt

变量 cnt 表示边的总数,每个边加入时的 cnt 为其编号

全局数组 head[u] 表示 以 u 为起点的第一条边的编号

边类的变量 nxt[i] 表示编号为 i 的边的下一条边

边类的变量 to[i] 表示编号为 i 的边的终点

建立边组时注意数组大小 N 为单向边的条数 建立双向边等于两个单向边

int head[N],cnt;
struct edge{
	int nxt;// 下一条边的编号
    int to;
    int weight;//边的其他属性
    .
    .
    .
} G[M]};//M为边的个数

Add 加边

void Add(){
	cnt++;// 边的总数加一 
	G[cnt].nxt=head[a];//新加入的边(cnt)的起点(a)的下一条边  为之前的加入的起点为 a 的 边的编号
	head[a]=cnt;// 将起点为 a 的第一条边的编号改为
	G[cnt].to=b;//边的终点
	G[cnt].weight=c;//边的边权
}

遍历边

遍历以 u 为起点的边

for(int i=head[u];i;t=G[u].nxt)
#include<iostream>
using namespace std;
struct edge{
	int nxt;
	int to;
	int weight;//边的权值
} G[1005];
int head[1005];
int n,m,cnt;// cnt 为边的总数,每个边加入时的cnt为其编号
void Add(int a,int b,int c){//添加边
	cnt++;// 边的总数加一 
	G[cnt].nxt=head[a];//新加入的边(cnt)的起点(a)的下一条边  为之前的加入的起点为 a 的 边的编号
	head[a]=cnt;// 将起点为 a 的第一条边的编号改为
	G[cnt].to=b;//边的终点
	G[cnt].weight=c;//边的边权
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1,a,b,c;i<=m;i++){
		scanf("%d%d%d",&a,&b,&c);
		Add(a,b,c);
	}
	for(int i=head[1];i!=0;i=G[i].nxt){//遍历以端点 1 为起点的所有边
		printf("%d ",G[i].to);
	}
	return 0;
}

链式前向星的LCA板子

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#define REP(i,a,b) for(int i=(a);i<=(b);i++)
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
using namespace std;
const int N = 40000 + 5;
typedef long long ll;
struct edge{
	int nxt;
	int to;
}G[N];//注意 这里的数组大小是变得总数 双向边建树需要开点数的二倍个点
int head[N],n,m,q,cnt,rt,dep[N],fa[N][35];
void SWAP(int &a,int &b){int t=a;a=b;b=t;}
void Add(int a,int b){
	cnt++;
	G[cnt].nxt=head[a];
	head[a]=cnt;
	G[cnt].to=b;
}
void dfs(int x,int f,int d){
	fa[x][0]=f;fa[x][1]=fa[f][0];
	dep[x]=d;
	for(int i=head[x];i;i=G[i].nxt){
		int u=G[i].to;
		if(u==f) continue;
		dfs(u,x,d+1);
	}
}
void init(){
	dfs(rt,-1,0);
	for(int k=0;k<=20;k++)
		REP(i,1,n)
			if(fa[i][k]<0) fa[i][k+1]=-1;
			else fa[i][k+1]=fa[fa[i][k]][k];
}
int lca(int u,int v){
	if(dep[u]>dep[v]) SWAP(u,v);
	int step=dep[v]-dep[u];
	for(int i=19;i>=0;i--)
		if(step&1<<i) v=fa[v][i];
	if(u==v) return u;
	for(int i=19;i>=0;i--)
		if(fa[u][i]!=fa[v][i]){
			u=fa[u][i];
			v=fa[v][i];
		}
	return fa[u][0];
}
void solve(){
	scanf("%d%d",&n,&q);
	FOR(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		Add(a,b);Add(b,a);
	}
	rt=1;
	init();
	while(q--){
		int a,b;
		scanf("%d%d",&a,&b);
		int c=lca(a,b);
		printf("%d\n",c);
	}
}
int main(){solve();return 0;}

标签:nxt,cnt,int,编号,head,板子,链式,include,前向星
来源: https://www.cnblogs.com/cookiecheetah/p/15097382.html