图的存储
方法一:邻接矩阵
用表来存储图。
- 优点:代码简单,便于理解。
- 缺点储存空间大,时间成本高。两点间存在多条边不能存储
代码:
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i!=j)Map[i][j]=inf;
else Map[i][j]=0;
}
//预处理图,自己到自己的距离为0,其它的为无穷大
for(int i=1;i<=m;i++){//一共m条边。
int u,v,d;
cin>>u>>v>>d;
Map[u][v]=d;//有向图
//Map[v][u]=d;(无向图)
}
也可以使用vector存储(相对减少空间)
- vector 的用法
声明函数:
vector<类型> 变量名
push_back();//在数组后面添加一个元素,数组长度自动+1
pop_back();//删除数组最后一个元素,无返回值,长度-1;
front(),back()//得到最前面,最后面一个元素
empty()//判断是否为空
size(),clear()//长度,清空
vector的遍历
1.像正常数组一样遍历。
2.运用指针
vector<int> vt;
vector<int>::iterator it;
for(it=vt.begin();it!=vt.end();it++)
cout<<*it;
注 :vector可以进行正常数组的下表操作。
vector存储图:
vector< pair<int,int> >G[10];
int main(){
int N,M;
cin>>N>>M;
for(int i=1;i<=M;i++){
int u,v,d;
cin>>u>>v>>d;
G[u].push_back(make_pair(d,v));
}//存储
int k;//查询第k条边
cin>>k;
for(int i=0;i<G[k].size();i++){
cout<<G[k][i].second<<" "<<G[k][i].first;
}//遍历
}
方法二:邻接链表
优点:可以通过边来讨论。
缺点:空间耗费大。
- 代码实现:
就是在邻接矩阵的基础上再加上一个存边的数组
//example
for(int i=1;i<=m;i++){
cin>>u>>v>>d;
B[u][0]++;//从u出发的边数+1
B[u][B[u][0]]=v;//从u出发的第B[u][0]条边为v;
map[u][v]=d;
}
方法三:边存储
优点:节省空间,可以存储多条边。
缺点:很少。
- 代码实现:
#define H 500005
#define LL long long
int N,M;
int NT[H],ED[H],LEN[H],LA[H],tot=0;
void LB(int u,int v,int d){
ED[++tot]=v;LEN[tot]=d;NT[tot]=LA[u];LA[u]=tot;
}
int main(){
cin>>N>>M;
for(int i=1;i<=M;i++){
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
LB(u,v,d);
}
//遍历:从x点开始的边
int x;
for(int i=LA[x];i;i=NT[i]){
int y=ED[i];
printf("%d %d",x,y);
}
}