在學最短路是就看見了這個東西,覺得會很難,今天終於開學這個知識了
前向星是一個存圖的工具,一種特殊的邊集數組
所以前向星數組對應的其實是邊的信息,下標就是邊的下標
前向星
前向星
把邊集數組中的每一條邊按照起點從小到大排序,如果起點相同就按照終點從小到大
並且記錄下以某個點為起點的所有邊在數組中的起始位置和存儲長度
len[i]數組記錄以i為起點的邊在數組中的儲存長度
head[i]數組記錄以i為邊集在數組中的第一個存儲位置(哪條邊)
輸入
1 2
2 3
3 4
1 3
4 1
1 5
4 5
排序得到的
編號 1 2 3 4 5 6 7
起點 1 1 1 2 3 4 4
終點 2 3 5 3 4 1 5
len[1]=3 head[1]=1
len[2]=1 head[2]=4
len[3]=1 head[3]=5
len[4]=2 head[4]=6
但是前向星會有排序操作,快排時間O(nlog(n))
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
int cnt = 0;
int head[N];//存儲起點為Vi的第一條邊的位置
struct note{
int from;
int to;
int w;
}edge[N];
bool cmp(note a, note b){//排序邏輯
if(a.from == b.from && a.to == b.to)return a.w < b.w;
if(a.from == b.from)return a.to < b.to;
return a.from < b.from;
}
void add(int u, int v, int w){
edge[cnt].from = u;
edge[cnt].to = v;
edge[cnt++].w = w;
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
sort(edge, edge + m, cmp);
memset(head, -1 ,sizeof(head));
head[edge[0].from] = 0;
for(int i = 1; i < m; i++){
if(edge[i].from != edge[i - 1].from)//確定起點為Vi的第一條邊的位置
head[edge[i].from] = i;
}
int start;
scanf("%d", &start);//輸出某個確定點的連接情況
for(int k = head[start]; edge[k].from == start && k < m; k++){
cout << edge[k].from << " " << edge[k].to << " "<< edge[k].w << endl;
}
return 0;
}
鏈式前向星
鏈式前向星
利用鏈式取儲存圖的情況
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e4 + 5;
int head[N];//鏈式地址
int cnt = 0;//邊的下標
struct node{
int next;//表示與第cnt條邊同起點的上一條邊的儲存位置
int to;
int w;
}e[N << 1]; // 一般對一條無向邊建立兩條有向邊
void add(int u, int v, int w){
e[cnt].w = w;//第cnt條邊的權值是w
e[cnt].to = v;//第cnt條邊的終點是v
e[cnt].next = head[u];//head[i]表示以i起點的最后一條邊的儲存位置
head[u] = cnt++;//head[];
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
memset(head, 0, sizeof(head));
while(m--){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w); add(v, u, w);
}
int start;
scanf("%d", &start);
for(int i = head[start]; i; i = e[i].next){//輸出某個指定結點的連接情況
cout << start << "->" << e[i].to << " " << e[i].w << endl;
}
return 0;
}