图论1—图的存储

图的存储

方法一:邻接矩阵

用表来存储图。

  • 优点:代码简单,便于理解。
  • 缺点储存空间大,时间成本高。两点间存在多条边不能存储

代码:

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);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go_bananas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值