邻接表-动态和静态的学习
来源:互联网 发布:edu.cn域名查询 编辑:程序博客网 时间:2024/05/16 01:14
上一篇用到了邻接表,这里学习一下数据结构。
我们知道图的保存方式有很多种,邻接矩阵adjMax【】【】,邻接表。。。。
邻接矩阵适合稠密图,而邻接表在表示稀疏图时很节省内存。
而邻接表又有动态和静态之分,静态和动态就不多做解释了,动态就是有多少用多少,静态你要提前分配好够用的内存,一般会比实际用的大一些。。。。
下面是静态表的一个实例
#include <iostream>#include <queue>using namespace std;const long edge_maxn = 1005; //边的最大上限const long point_maxn = 105; //点的最大上限struct node{/*node存储边,一个edge代表一条边*/int v; //终点位置int w; //权值int next; //同一起点的下一条边存储在edge数组中的位置(理解了这个静态邻接表就可以了)}edge[edge_maxn];int pre[point_maxn]; //以该点为起点的第一条边存储在edge数组中的位置int n; //点的数量int m; //边的数量void Init(){memset(pre,-1,sizeof(pre));int Index = 1;int i,x,y,w;for(i=0;i<m;i++){scanf("%d%d%d",&x,&y,&w);edge[Index].v = y;edge[Index].w = w;edge[Index].next = pre[x]; //保存x起点的上一条边在edge数组中的位置pre[x] = Index++; //位置更新}}void print(){for(int i=1;i<=n;i++){printf("%d/n",i);for(int j=pre[i];j!=-1;j=edge[j].next){printf(" -> %d value is %d/n",edge[j].v,edge[j].w);}//printf("/n");}}int main(){while(scanf("%d%d",&n,&m)!=EOF && (n!=0 || m!=0)){Init();print();}return 0;}
下面是动态表的实例,以poj1511为例
#include<iostream>#include<cmath>#include<queue>using namespace std;#define MAX_NUM 1000000001#define MAX_DOTNUM 1000001int n,m;queue<int>myqueue;bool mark[MAX_DOTNUM];__int64 dis[MAX_DOTNUM];struct node{ int v; int w; node *next;}edge[MAX_DOTNUM];//此邻接表用于存储正向图node reversed_edge[MAX_DOTNUM];//此逆邻接表用于存储逆向图void initial(node edge[])//邻接表的初始化,里面封装了回收上一次操作所分配之内存的操作{ int i; node *p; node *q; for(i=1;i<=n;i++) { p=&edge[i]; q=p->next; while(q!=NULL) { p->next=q->next; delete q; q=p->next; } }}void input_case()//每一个case的输入函数{ int i; for(i=1;i<=m;i++) { node *p; node *q; int a,b,c; scanf("%d%d%d",&a,&b,&c); /**///////////////////////// p=&edge[a]; q=new node; q->v=b; q->w=c; q->next=p->next; p->next=q; /**///////////////////////// p=&reversed_edge[b]; q=new node; q->v=a; q->w=c; q->next=p->next; p->next=q; }}void spfa(node edge[])//SPFA部分{ int i; /**//////////////////////////////////////////////////////////////// memset(mark,false,sizeof(mark)); for(i=1;i<=n;i++) dis[i]=MAX_NUM; while(myqueue.size()!=0) myqueue.pop(); /**//////////////////////////////////////////////////////////// dis[1]=0; mark[1]=true; myqueue.push(1); while(myqueue.size()!=0)//如果队列不空,则进行松弛操作,直到队列空为止 { int temp=myqueue.front(); myqueue.pop(); mark[temp]=false; node *p; for(p=edge[temp].next;p!=NULL;p=p->next) { if(dis[p->v]>dis[temp]+p->w) { dis[p->v]=dis[temp]+p->w; if(mark[p->v]!=true) { myqueue.push(p->v); mark[p->v]=true; } } } }}int main(){ int testcase; int i,j; __int64 sum; scanf("%d",&testcase); for(i=1;i<=MAX_DOTNUM-1;i++) { edge[i].v=i; edge[i].w=0; edge[i].next=NULL; } for(i=1;i<=MAX_DOTNUM-1;i++) { reversed_edge[i].v=i; reversed_edge[i].w=0; reversed_edge[i].next=NULL; } for(i=1;i<=testcase;i++) { sum=0; scanf("%d%d",&n,&m); initial(edge); initial(reversed_edge); input_case(); spfa(edge); for(j=1;j<=n;j++) sum+=dis[j]; spfa(reversed_edge); for(j=1;j<=n;j++) sum+=dis[j]; printf("%I64d\n",sum); } system("pause"); return 0;}
- 邻接表-动态和静态的学习
- 静态邻接表的建立
- 动态代理和静态代理的学习
- 静态邻接表的简单实现
- 静态邻接表
- 静态邻接表
- 静态邻接表模版
- 静态邻接表
- 静态邻接表
- 静态邻接表
- 顺序表的静态和动态实现
- 静态代理和动态代理的再学习
- Java学习笔记-数组的静态初始化和动态初始化
- SPFA + 静态邻接表 模板
- poj 1511 Invitation Cards 静态邻接表的SPFA
- vector动态数组邻接表--功能更强大的邻接表
- 静态库和动态库学习
- 静态代理和动态代理学习笔记
- 大公司php面试题汇总
- JadClipse下载安装
- Intent的应用(初识intent)
- JSP web.xml 配置详解
- android 有关Activity的Launch mode 以及Intent的setFlags
- 邻接表-动态和静态的学习
- Aria2 下载工具安装和使用(ubuntu,fredora)
- JAVA另一种做日期加减法的方法(更简单)
- 如何调试NodeJS
- vc隐藏执行程序,即不显示窗体执行
- hdu 1541
- SQL server语言基础(一)
- jquery基础一
- PHP学习之七:扩展函数库-文件系统、进程与网络