邻接表-动态和静态的学习

来源:互联网 发布: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;}