图的储存
边数和点数成正比的叫稠密图,点多边少的叫稀疏图
一个图中的所有顶点度之和相加除以二等于边数
邻接矩阵:适用于边多的图
对于无向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的度。
对于有向图,邻接矩阵的第i行(或第i列)非零元素(或非∞元素)的个数正好是第i个顶点的出度(或入度)
int main(){
memset(G,INF,sizeof(G));//初始化数组G为INF
int u, v, w;
int n, m;
scanf("%d%d", &n, &m);
while(m--){
scanf("%d%d%d", &u, &v, &w);
G[u][v] = G[v][u] = w;
//G[u][v] = w;有向图
}
for (int i = 0; i < n;i++){
for (int j = 0; j < n;j++){
printf("%d ", G[i][j]);
}
printf("\n");
}
return 0;
}
链式前向星
edge[i]表示第i条边;head[i]存以i为起点的最后一条边的编号; edge[i].pre记录与这个边起点相同的上一条边的编号
int head[maxn];//maxn是边的数量,无向图开2倍
struct Edge{
int to,w,pre;
}edge[maxn];
int node;
void init(){
memset(head,-1,sizeof(head));//初始化没有边
node=0;
}
void add_edge(int a,int b,int c){
edge[node].to=b;
edge[node].w=c;
edge[node].pre=head[a];
head[a]=node++;
}
int main(){
int n,m;
cin>>n>>m;
init();
for(int i=1;i<=m;++i){
int a,b,c;
cin>>a>>b>>c;
add_edge(a,b,c);
add_edge(b,a,c);
}
for(int i=1;i<=n;++i){
cout<<i;
for(int j=head[i];j!=-1;j=edge[j].pre){
cout<<"->"<<edge[j].to;//倒序输出
}
cout<<endl;
}
return 0;
}
链表版:
const int N = 1e5+5;//点数
const int M = 1e6+5;
int head[N],e[M],en[M],w[M];//头结点,e数组存值,en数组存指向的下一个下标
void init(){
memset(head,-1,sizeod head);
index = 0;
}
void add(int a,int b){//在结点a的单链表的头结点插入b
e[index]=b;en[index]=head[a];head[a]=index++;
}