常用的建图方式(邻接矩阵,静态链表,Vector,链式向前星)

今天才发现自己原来基础的东西有些都不是很懂,就比如存图的方式,就只会最简单的邻接矩阵和静态链表。所以昨天的多校就炸了,QAQ,发现自己只会用板子,板子的意思都不是很懂,所以今天专门来补一下这方面的知识,也是做个笔记。

最简单的邻接矩阵来存储图,这个不用多说,上代码

#include 
using namespace std;
int G[500][500];
int n,m;
int main(int argc, char** argv) {
	scanf("%d%d",&n,&m);
	for(int i = 1;i<=m;++i){
		int x,y,w;
		scanf("%d%d%d",&x,&y,&w);
		G[x][y]=w;//有向图 
	} 
	for(int i = 1;i<=n;++i){
		for(int j = 1;j<=n;++j){
			printf("%d ",G[i][j]);
		}
		printf("\n");
	}
	return 0;
}

静态链表建图,用数组来实现链表实现的功能,只不过遍历时是反着来的,可以参考这个博文:静态链表

#include 
using namespace std;
const int maxn=1e5+7;
int u[maxn],v[maxn],w[maxn];//u,v,i分别表示边的起点,终点和权值 
int next[maxn],head[maxn];//head 存储每个顶点其中边的编号,next数组存储编号为 i 的边的前一条边的编号 
//head数组相当于链表中的最后一个空指针,next数组相当于链表里面的指针,只不过存储的是前一条边的编号,
//那么我们遍历每个顶点就是从该点的最后一条边开始遍历,从后往前回溯。 
int n,m;//n,m表示顶点数和边数 
int main(int argc, char** argv) {
	//这个过程类似于链表的头插法 
	while(~scanf("%d%d",&n,&m)){
		for(int i = 1;i<=n;++i) head[i]=-1;
		for(int i = 1;i<=m;++i){
			scanf("%d%d%d",&u[i],&v[i],&w[i]);
			next[i]=head[u[i]]; 
			head[u[i]]=i;//最重要的两句话, 
		}
		for(int i = 1;i<=n;++i){
			int j = head[i];//遍历每个顶点的所有边 
			while(j!=-1){
				printf("%d %d %d\n",u[i],v[i],w[i]);
				j=next[j];
			}
			cout<

用STL中的vector来建图.(不过有的会卡这个,而且还不能存权值)

#include 
#include
using namespace std;
vector G[100];
int n,m;
int main(int argc, char** argv) {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);//有向图 
	}
	for(int i = 1;i<=n;++i){
		for(int j = 0;j

最后来一个最牛逼的建图方法,也是最难理解的!!!!

链式向前星建图(没错,就是大佬代码里你最先看不懂的那部分)

这里推荐一篇好的文章,链式向前星

#include 
#include
using namespace std;
const int maxn=1e5+7;
struct Edge{
	int to;
	int w;
	int next;
}edge[maxn]; 
int cnt=0;
int head[maxn];
int n,m;
void addEdge(int from,int to,int w){
	edge[cnt].to=to;
	edge[cnt].w=w;
	edge[cnt].next=head[from];
	head[from]=cnt++;
}
int main(int argc, char** argv) {
	scanf("%d%d",&n,&m);
	memset(head,-1,sizeof(head));
	memset(edge,-1,sizeof(edge));
	for(int i = 1;i<=m;++i){
		int x,y,w;
		scanf("%d%d%d",&x,&y,&w);
		addEdge(x,y,w);
	}
	for(int i = 1;i<=n;++i){
		int t=head[i];
		while(t!=-1){
			printf("from %d to %d is %d\n",i,edge[t].to,edge[t].w);
			t=edge[t].next;
		}
	}
	return 0;
}

 

你可能感兴趣的:(杂记,建图)