标签:
运用三种方式来实现图的存储,以适应不同的情况。
参考:ACM-ICPC程序设计系列——图论及应用
方式1:邻接矩阵
邻接矩阵是表示图的数据结构中最简单也是最常用的一种。
实现:二维数组Map[MAXN][MAXN],Map[i][j]表示点i到点j的距离。
初始化:Map[i][i] = 0,Map[i][j] = INF(i!=j),读入数据Map[i][j] = w。
时间复杂度:初始化O(n^2),建图需要O(m),总时间复杂度O(n^2)。
优缺点:简单直观,可直接查询点i和点j之间是否有边;遍历效率低,不
能存储重编;初始化效率低;大图开销大,适合存储点少的稠密图。
方式2:前向星
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100;
const int MAXM = 100;
int head[MAXN];//存储起点为i的第一条边的位置
struct node
{
int from;//起点
int to;//终点
int w;//权值
};
node edge[MAXM];
bool cmp(node a,node 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;
}
int main()
{
int n,m;
cin >> n >> m;
for(int i = 0; i < m; i++)
{
cin >> edge[i].from >> edge[i].to >> edge[i].w;
}
sort(edge,edge+m,cmp);
memset(head,-1,sizeof(head));
head[edge[0].from] = 0;
for(int i = 1; i < m; i++)//确定起点为i的第一条边位置
{
if(edge[i].from != edge[i-1].from)
head[edge[i].from] = i;
}
for(int i = 1; i <= n; i++)//遍历图
{
//k为第i个结点边的起始位置
for(int k = head[i]; edge[k].from == i && k < m; k++)
{
cout << edge[k].from << ' ' << edge[k].to << ' ' << edge[k].w << endl;
}
}
return 0;
}
/*
7 8
1 1 1
1 3 1
1 3 2
3 5 1
3 6 1
4 6 1
2 4 1
1 2 1
*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100;
struct EdgeNode<span style="white-space:pre"> </span>//邻接表节点
{
int to;<span style="white-space:pre"> </span>//终点
int w;<span style="white-space:pre"> </span>//权值
EdgeNode *next;<span style="white-space:pre"> </span>//指向下一条边的指针
};
struct VNode<span style="white-space:pre"> </span>//起点表节点
{
int from;<span style="white-space:pre"> </span>//起点
EdgeNode *first;<span style="white-space:pre"> </span>//邻接表头指针
};
VNode Adjlist[MAXN];<span style="white-space:pre"> </span>//整个图的邻接表
int main()
{
int n,m,x,y,w;
cin >> n >> m;
for(int i = 0; i < m; i++)//读入图
{
cin >> x >> y >> w;
EdgeNode *p = new EdgeNode();
p->to = y;
p->w = w;
p->next = Adjlist[x].first;
Adjlist[x].first = p;
}
cout << endl;
for(int i = 1; i <= n; i++)//遍历图
{
for(EdgeNode *k = Adjlist[i].first; k != NULL; k = k->next)
cout << i << ' ' << k->to << ' ' << k->w << endl;
}
return 0;
}
方式4:邻接表——vector模拟链表实现
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100;
const int MAXM = 100;
struct EdgeNode<span style="white-space:pre"> </span>//边表节点类型
{
int to;<span style="white-space:pre"> </span>//终点
int w;<span style="white-space:pre"> </span>//权值
};
vector<EdgeNode> Map[MAXN];
int main()
{
EdgeNode e;
int n,m,x,y,w;
cin >> n >> m;
for(int i = 0; i < m; i++)<span style="white-space:pre"> </span>//读入图
{
cin >> x >> y >> w;
e.to = y;
e.w = w;
Map[x].push_back(e);
}
cout << endl;
for(int i = 1; i <= n; i++)<span style="white-space:pre"> </span>//遍历图
{
for(vector <EdgeNode>::iterator k = Map[i].begin(); k!=Map[i].end(); k++)
{
EdgeNode t = *k;
cout << i << ' ' << t.to << ' ' << t.w << endl;
}
}
return 0;
}
方式5:邻接表——链式前向星★
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 100;
const int MAXM = 100;
int head[MAXN];
struct EdgeNode
{
int to;
int w;
int next;
};
EdgeNode Edges[MAXM];
int main()
{
int n,m,x,y,w;
cin >> n >> m;
memset(head,-1,sizeof(head));
for(int i = 0; i < m; i++)
{
cin >> x >> y >> w;
Edges[i].to = y;
Edges[i].w = w;
Edges[i].next = head[x];
head[x] = i;
}
cout << endl;
for(int i = 1; i <= n; i++)
{
for(int k = head[i]; k!= -1; k = Edges[k].next)
cout << i << ' ' << Edges[k].to << ' ' << Edges[k].w << endl;
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/42108099