一. vector形式
1. 特性分析
- 优点:代码简单,均摊时间代价也不是很大
- 缺点:性能确实没那么高,当考虑边的权值是还需另外定义struct,遍历也不再方便
- 适用情形:只考虑连通性的稀疏图
2. 代码实现
#include <vector>
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 <iostream>
#include <string>
#include <algorithm>
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;
}