图论-图的存储(邻接表)探究

一. vector形式

1. 特性分析

  • 优点:代码简单,均摊时间代价也不是很大
  • 缺点:性能确实没那么高,当考虑边的权值是还需另外定义struct,遍历也不再方便
  • 适用情形:只考虑连通性的稀疏图

2. 代码实现

#include 

using namespace std;
const int maxn=2e4+10;

int n,m;
vector<int> edges[maxn];

//图的录入
int u,v;
scanf("%d%d",&u,&v);
edges[u].push_back(v);

//边的遍历
for(int v:edges[u)
{
    //访问边 
    //...
}

二. 链式向前星(模拟链表)

1. 特性分析

  • 优点:比链表代码简单,性能高、空间占用小,考虑边的权值时仍很方便
  • 缺点:实现不如vector形式简单
  • 适用情形:考虑边的权值时的稀疏图
  • 备注:特别地,当处理最大网络流问题时,使用链式向前星可以方便地回去正向边和对应的反向边

2. 代码实现

using namespace std;
const int N=1e4+10,E=2e5+10,INF=1<<30;//注意边集应为双倍!!!

int n,m,s,t;
int idx=2,first[N],nxt[E],to[E],val[E];

//图的录入
inline void addE(int u,int v,int w)
{
    to[idx]=v,val[idx]=w;
    nxt[idx]=first[u];
    first[u]=idx++;
}

//边的遍历
for(int p=first[u];p;p=nxt[p])
{
    int v=to[p],w=val[p];
    //访问边 
    //...
}

三. 邻接链表

1. 特性分析

  • 优点:结构严谨,看着清楚
  • 缺点:实现比较复杂,容易写错
  • 适用情形:一般不使用(适合工程中使用)

2. 代码实现

#include 
#include 
#include 

using namespace std;

struct ArcNode
{
    int u,v,w;
    ArcNode * next;

    ArcNode(){}
    ArcNode(int _u,int _v,int _w,ArcNode * _next):u(_u),v(_v),w(_w),next(_next){}
};

struct VNode
{
    ArcNode * first_arc;
};

struct Graph
{
    int n;
    int m;
    
    VNode * vec;
    

    Graph(int _n,int _m)
    {
        n=_n,m=_m;
        vec=new VNode[n+1];
        for(int i=0;i<=n;i++)
            vec[i].first_arc=nullptr;
    }

    ~Graph()
    {
        for(int i=0;i<=n;i++)
        {
            ArcNode * arc=vec[i].first_arc;
            while(arc)
            {
                vec[i].first_arc=arc->next;
                delete arc;
                arc=vec[i].first_arc;
            }
            delete [] vec;
        }
    }

    void create()
    {
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            cin>>u>>v>>w;
            ArcNode * newNode=new ArcNode(u,v,w,vec[u].first_arc);
            vec[u].first_arc=newNode;
        }
    }

    void show()
    {
        for(int i=1;i<=n;i++)
        {
            cout<<i<<"==>";
            ArcNode * arc=vec[i].first_arc;
            while(arc)
            {
                cout<<arc->v<<" ";
                arc=arc->next;
            }
            cout<<endl;
        }
    }
};

int main()
{
    int n,m;
    cin>>n>>m;
    Graph graph(n,m);
    graph.create();
    graph.show();
    return 0;
}

你可能感兴趣的:(算法学习)