基础建图
基础建图
1)竞赛一边使用邻接矩阵,邻接表,和链式前向星法建图
1.1)邻接矩阵:
用一个二维数组来表示图,下标表示结点,例如:a[3][4] = 1;表示有一条 3 -> 4 的边,如果有权值,则将1替换为权值
代码:
const int MAX = 100;
vector<vector<int>>graph(MAX,vector<int>(MAX));
void bulid(vector<vector<int>>&edges){
for(const auto & edge : edges){
graph[edge[0]][edge[1]] = 1;
}
}
1.2)邻接表
用多个链表表示图,链表的编号代表和链表中存的值为结点
代码:
int n;
vector<vector<int>>graph(n);
void build(vector<vector<int>>&edges){
for(const auto &edge : edges){
graph[edge[0]].push_back(edge[1]);
}
}
1.3)链式前向星
用数组来模拟链表
代码:
//结点的数量
const int n;
//边的数量
const int m;
//记录第几条边
int cnt;
int head[n];
int nxt[m];
int to[m];
void addEdge(int u,int v){
nxt[cnt] = head[u];
head[u] = cnt;
to[cnt] = v;
cnt++;
}
void bulid(vector<vector<int>>&edges){
for(int i = 0;i<n;i++){
head[i] = 0;
}
for(const auto &edge : edges){
int u = edge[0];
int v = edge[1];
addEdge(u,v);
}
}
2.2)详细代码:
#include<iostream>
#include<list>
#include<vector>
using namespace std;
//基本建图
const int MAXN = 11;
const int MAXM = 21;
//邻接矩阵建图
int graph1[MAXN][MAXN];
//邻接表建图
//无权
vector<vector<int>>graph2;
//带权
vector<vector<pair<int,int>>>graph2_2;
//链式前向星
//用来存头边,下标为点,初始时为0表示无边
int head[MAXN];
//用来指向下一条边,下标为边
int nextt[MAXM];
//用来指向指向的节点,下标为边
int to[MAXM];
//用来记录权重,下标为边
int wweight[MAXM];
//用来记录边的编号
int cnt;
//建图准备
void build(int n){
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
graph1[i][j] = 0;
}
}
graph2_2.clear();
for(int i = 0;i<=n;i++){
graph2_2.push_back(vector<pair<int,int>>());
}
cnt = 1;
for(int i = 0;i<=n;i++){
head[i] = 0;
}
}
//链式前向星加边 , 用数组模拟头插法
void addedge(int u,int v,int w){
//u 到 v 权重为 w 的边
nextt[cnt] = head[u];
to[cnt] = v;
wweight[cnt] = w;
head[u] = cnt++;
}
//建立有向带权图
void directGraph(vector<vector<int>>&edge){
int len = edge.size();
//邻接矩阵
//edge[i] 中的 0 代表出发节点 1 代表结束节点, 2 代表权值
for(int i = 0;i<len;i++){
graph1[edge[i][0]][edge[i][1]] = edge[i][2];
}
//邻接表
for(int i = 0;i<len;i++){
int from = edge[i][0];
int to = edge[i][1];
int weight = edge[i][2];
graph2_2[from].push_back({to,weight});
}
//链式前向星
for(const auto &e : edge){
addedge(e[0],e[1],e[2]);
}
}
//无向带权图
void undirectGraph(vector<vector<int>>&edge){
int len = edge.size();
for(int i = 0;i<len;i++){
graph1[edge[i][0]][edge[i][1]] = edge[i][2];
graph1[edge[i][1]][edge[i][0]] = edge[i][2];
}
for(const auto& e : edge){
int from = e[0];
int to = e[1];
int weight = e[2];
graph2_2[from].push_back({to,weight});
graph2_2[to].push_back({from,weight});
}
//链式前向星
for(const auto& e:edge){
addedge(e[0],e[1],e[2]);
addedge(e[1],e[0],e[2]);
}
}
//遍历
void traversal(int n){
//邻接矩阵
cout << "neigherMatrix: " << endl;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
cout << graph1[i][j] << " ";
}
cout << endl;
}
//邻接表
cout << "neighberList:neighber,weight: " << endl;
for(int i = 1;i<=n;i++){
cout << i << ":";
for(const auto&t: graph2_2[i]){
cout << "(" << t.first << " " << t.second << ") ";
}
cout << endl;
}
//链式前向星
cout << "I dont know what is call in english:" << endl;
for(int i = 1;i<=n;i++){
cout << i << ":";
for(int ei = head[i];ei > 0;ei = nextt[ei]){
cout <<"(" << to[ei] << " " << wweight[ei] << ")";
}
cout << endl;
}
}
int main(){
int n1 = 4;
//有向带权图
vector<vector<int>>a = {
{ 1, 3, 6 },
{ 4, 3, 4 },
{ 2, 4, 2 },
{ 1, 2, 7 },
{ 2, 3, 5 },
{ 3, 1, 1 }
};
build(n1);
directGraph(a);
traversal(n1);
cout << "------------------------------------------" << endl;
//无向带权值图
int n2 = 5;
vector<vector<int>>b = {
{ 3, 5, 4 },
{ 4, 1, 1 },
{ 3, 4, 2 },
{ 5, 2, 4 },
{ 2, 3, 7 },
{ 1, 5, 5 },
{ 4, 2, 6 }
};
build(n2);
undirectGraph(b);
traversal(n2);
return 0;
}
浙公网安备 33010602011771号